<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000-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/>.
 *
 * $ Id: $
 *
 */

#if !defined(XALAN_NAMESPACESHANDLER_HEADER_GUARD)
#define XALAN_NAMESPACESHANDLER_HEADER_GUARD

// Base include file.  Must be first.
#include <XSLT/XSLTDefinitions.hpp>

#include <map>
#include <set>
#include <vector>

#include <PlatformSupport/DOMStringHelper.hpp>

#include <XPath/NameSpace.hpp>
#include <XPath/XalanQName.hpp>

XALAN_CPP_NAMESPACE_BEGIN

class StylesheetConstructionContext;
class StylesheetExecutionContext;

class XALAN_XSLT_EXPORT NamespacesHandler
{
public:

	class PrefixChecker
	{
	public:

		PrefixChecker();

		virtual
		~PrefixChecker();

		virtual bool
		isActive(const XalanDOMString&	thePrefix) const = 0;
	};

	class XALAN_XSLT_EXPORT Namespace
	{
	public:

		Namespace() :
			m_prefix(&s_emptyString),
			m_uri(&s_emptyString)
		{
		}

		Namespace(
					const XalanDOMString&	prefix,
					const XalanDOMString&	uri) :
			m_prefix(&prefix),
			m_uri(&uri)
		{
		}

		/**
		 * Retrieve the prefix for namespace
		 *
		 * @return prefix string
		 */
		const XalanDOMString&
		getPrefix() const
		{
			assert(m_prefix != 0);

			return *m_prefix;
		}

		/**
		 * Set the prefix for namespace
		 *
		 * @param prefix The new prefix value
		 */
		void
		setPrefix(const XalanDOMString&		prefix)
		{
			m_prefix = &prefix;
		}

		/**
		 * Retrieve the URI for namespace
		 *
		 * @return URI string
		 */
		const XalanDOMString&
		getURI() const
		{
			assert(m_uri != 0);

			return *m_uri;
		}

		/**
		 * Set the URI for namespace
		 *
		 * @param uri The new uri value
		 */
		void
		setURI(const XalanDOMString&	uri)
		{
			m_uri = &uri;
		}

	protected:

		static const XalanDOMString		s_emptyString;

	private:

		const XalanDOMString*	m_prefix;

		const XalanDOMString*	m_uri;
	};

	class XALAN_XSLT_EXPORT NamespaceExtended : public Namespace
	{
	public:

		NamespaceExtended() :
			Namespace(),
			m_resultAttributeName(&s_emptyString)
		{
		}

		NamespaceExtended(
					const XalanDOMString&	prefix,
					const XalanDOMString&	uri) :
			Namespace(prefix, uri),
			m_resultAttributeName(&s_emptyString)
		{
		}

		/**
		 * Retrieve the name of the result attribute.
		 *
		 * @return name string
		 */
		const XalanDOMString&
		getResultAttributeName() const
		{
			assert(m_resultAttributeName != 0);

			return *m_resultAttributeName;
		}

		/**
		 * Set the name of the result attribute.
		 *
		 * @param name The new name value
		 */
		void
		setResultAttributeName(const XalanDOMString&	name)
		{
			m_resultAttributeName = &name;
		}

	private:

		const XalanDOMString*	m_resultAttributeName;
	};

	typedef XalanQName::NamespaceVectorType				NamespaceVectorType;
	typedef XalanQName::NamespacesStackType				NamespacesStackType;

#if defined(XALAN_NO_STD_NAMESPACE)
	typedef vector<Namespace>							NamespacesVectorType;

	typedef vector<NamespaceExtended>					NamespaceExtendedVectorType;

	typedef map<const XalanDOMString*,
				const XalanDOMString*,
				DOMStringPointerLessThanFunction>		ExcludedResultPrefixesMapType;

	typedef map<const XalanDOMString*,
				NamespaceExtended,
				DOMStringPointerLessThanFunction>		NamespacesMapType;

	typedef map<const XalanDOMString*,
				const XalanDOMString*,
				DOMStringPointerLessThanFunction>		NamespaceAliasesMapType;

	typedef vector<const XalanDOMString*>				XalanDOMStringPointerVectorType;
#else
	typedef std::vector<Namespace>						NamespacesVectorType;

	typedef std::vector<NamespaceExtended>				NamespaceExtendedVectorType;

	typedef std::map<const XalanDOMString*,
					 const XalanDOMString*,
					 DOMStringPointerLessThanFunction>	ExcludedResultPrefixesMapType;

	typedef std::map<const XalanDOMString*,
					 NamespaceExtended,
					 DOMStringPointerLessThanFunction>	NamespacesMapType;

	typedef std::map<const XalanDOMString*,
					 const XalanDOMString*,
					 DOMStringPointerLessThanFunction>	NamespaceAliasesMapType;

	typedef std::vector<const XalanDOMString*>			XalanDOMStringPointerVectorType;
#endif

	/**
	 * Create a default, empty instance.
	 */
	explicit
	NamespacesHandler();

	/**
	 * Create an instance namespace handler using the
	 * current namespaces in effect.
	 *
	 * @param theConstructionContext The current construction context.
	 * @param stylesheetNamespacesHandler The stylesheet's handler.
	 * @param theCurrentNamespaces The stack of active namespace declarations.
	 * @param theXSLTNamespaceURI The namespace URI for XSLT.
	 */
	NamespacesHandler(
			StylesheetConstructionContext&	theConstructionContext,
			const NamespacesHandler&		stylesheetNamespacesHandler,
			const NamespacesStackType&		theCurrentNamespaces,
			const XalanDOMString&			theXSLTNamespaceURI);

	~NamespacesHandler();

	/**
	 * Process an exclude-result-prefixes attribute.
	 *
	 * @param theConstructionContext The current construction context.
	 * @param theValue The attribute's value.
	 * @param theCurrentNamespaces The stack of active namespace declarations.
	 */
	void
	processExcludeResultPrefixes(
			StylesheetConstructionContext&	theConstructionContext,
			const XalanDOMChar*				theValue,
			const NamespacesStackType&		theCurrentNamespaces);

	/**
	 * Process an extension-element-prefixes attribute.
	 *
	 * @param theConstructionContext The current construction context.
	 * @param theValue The attribute's value.
	 * @param theCurrentNamespaces The stack of active namespace declarations.
	 */
	void
	processExtensionElementPrefixes(
			StylesheetConstructionContext&	theConstructionContext,
			const XalanDOMChar*				theValue,
			const NamespacesStackType&		theCurrentNamespaces);

	/**
	 * Notify the instance that the stylesheet is fully constructed.
	 *
	 * @param theConstructionContext The current construction context.
	 * @param fProcessNamespaceAliases If true, process any namespace aliases
	 * @param theElementName The name of the owning element.
	 * @param parentNamespacesHandler The parent handler, if any.
	 * @param prefixChecker A pointer to a PrefixChecker instance to use, if any.
	 */
	void
	postConstruction(
			StylesheetConstructionContext&	theConstructionContext,
			bool							fProcessNamespaceAliases = true,
			const XalanDOMString&			theElementName = XalanDOMString(),
			const NamespacesHandler*		parentNamespacesHandler = 0,
			const PrefixChecker*			prefixChecker = 0);

	NamespacesHandler&
	operator=(const NamespacesHandler&	theRHS);

	/**
	 * Determine of a given namespace should be excluded.
	 *
	 * @param theXSLTNamespaceURI The namespace URI for XSLT.
	 * @param theURI The namespace URI.
	 * @return true of the namespace should be excluded, false if not.
	 */
	bool
	shouldExcludeResultNamespaceNode(
			const XalanDOMString&	theXSLTNamespaceURI,
			const XalanDOMString&	theURI) const;

	/**
	 * Add a URI as an extension namespace prefixes.
	 *
	 * @param theConstructionContext The current construction context.
	 * @param theURI The namespace URI.
	 */
	void
	addExtensionNamespaceURI(
			StylesheetConstructionContext&	theConstructionContext,
			const XalanDOMString&	theURI);

	/**
	 * Get the namespace URI for the given prefix.
	 *
	 * @param thePrefix The namespace prefix.
	 * @return The namespace URI
	 */
	const XalanDOMString*
	getNamespace(const XalanDOMString&	thePrefix) const;

	/**
	 * Get the namespace alias URI for the given namespace.
	 *
	 * @param theStylesheetNamespace The namespace as declared in the stylesheet.
	 * @return The namespace alias URI
	 */
	const XalanDOMString*
	getNamespaceAlias(const XalanDOMString&		theStylesheetNamespace) const;

	/**
	 * Set the namespace alias URI for the given namespace.
	 *
	 * @param theConstructionContext The current construction context.
	 * @param theStylesheetNamespace The namespace as declared in the stylesheet.
	 * @param theResultNamespace The namespace as it should appear in the result tree.
	 */
	void
	setNamespaceAlias(
			StylesheetConstructionContext&	theConstructionContext,
			const XalanDOMString&			theStylesheetNamespace,
			const XalanDOMString&			theResultNamespace);

	/**
	 * Copy the aliases from the given NamespacesHandler.
	 *
	 * @param parentNamespacesHandler The parent handler.
	 */
	void
	copyNamespaceAliases(const NamespacesHandler&	parentNamespacesHandler);

	/**
	 * Output the result tree namespace declarations.
	 *
	 * @param theExecutionContext The current execution context.
	 * @param supressDefault If true, any default namespace declaration will not be output.
	 */
	void
	outputResultNamespaces(
			StylesheetExecutionContext&		theExecutionContext,
			bool							supressDefault = false) const;

	/**
	 * Clear out the handler.
	 */
	void
	clear();

	/**
	 * Swap the contents of this instance with another.
	 *
	 * @param theOther The other instance.
	 */
	void
	swap(NamespacesHandler&		theOther);

	NamespacesMapType::size_type
	getNamespaceDeclarationsCount() const
	{
		return m_namespaceDeclarations.size();
	}

private:

	/**
	 * Create all of the result attribute names.
	 *
	 * @param theConstructionContext The current construction context.
	 */
	void
	createResultAttributeNames(StylesheetConstructionContext&	theConstructionContext);

	/**
	 * Process the exclude result prefix data.
	 *
	 * @param theConstructionContext The current construction context.
	 * @param theElementPrefix The prefix of the owning element.
	 * @param prefixChecker A pointer to a PrefixChecker instance to use, if any.
	 */
	void
	processExcludeResultPrefixes(
			StylesheetConstructionContext&	theConstructionContext,
			const XalanDOMString&			theElementPrefix,
			const PrefixChecker*			prefixChecker);

	/**
	 * Process the namespace aliases data.
	 */
	void
	processNamespaceAliases();

	/**
	 * Copy the contents of the supplied map
	 *
	 * @param theNamespaceAliases The map to copy.
	 */
	void
	copyNamespaceAliases(const NamespaceAliasesMapType&		theNamespaceAliases);

	/**
	 * Copy the contents of the supplied vector
	 *
	 * @param theExtensionNamespaceURIs The set to copy.
	 */
	void
	copyExtensionNamespaceURIs(const XalanDOMStringPointerVectorType&	theExtensionNamespaceURIs);

	/**
	 * Copy the contents of the supplied vector
	 *
	 * @param theExcludeResultPrefixes The vector to copy.
	 */
	void
	copyExcludeResultPrefixes(const NamespacesVectorType&	theExcludeResultPrefixes);

	/**
	 * Determine if a given namespace should be excluded as a result of
	 * an exclude-result-prefixes declaration.
	 *
	 * @param theNamespaceURI The namespace URI to check.
	 * @return true if the namespace should be excluded, false if not.
	 */
	bool
	isExcludedNamespaceURI(const XalanDOMString&	theNamespaceURI) const;

	/**
	 * Determine if a given URI is an extension namespace URI
	 *
	 * @param theNamespaceURI The namespace URI to check.
	 * @return true if the namespace uri is an extension namespace URI, false if not.
	 */
	bool
	isExtensionNamespaceURI(const XalanDOMString&	theNamespaceURI) const
	{
		return findString(theNamespaceURI, m_extensionNamespaceURIs);
	}

	/**
	 * Determine if a given string is present in the vector
	 *
	 * @param theString The string to find.
	 * @return true if the string is present, false if not.
	 */
	static bool
	findString(
			const XalanDOMString&					theString,
			const XalanDOMStringPointerVectorType&	theVector);

	// Not implemented...
	bool
	operator==(const NamespacesHandler&) const;

	// Data members...
	NamespacesVectorType				m_excludedResultPrefixes;

	NamespaceExtendedVectorType			m_namespaceDeclarations;

	XalanDOMStringPointerVectorType		m_extensionNamespaceURIs;

	NamespaceAliasesMapType				m_namespaceAliases;
};

XALAN_CPP_NAMESPACE_END

#endif	// XALAN_NAMESPACESHANDLER_HEADER_GUARD
<commit_msg>Added missing export.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000-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/>.
 *
 * $ Id: $
 *
 */

#if !defined(XALAN_NAMESPACESHANDLER_HEADER_GUARD)
#define XALAN_NAMESPACESHANDLER_HEADER_GUARD

// Base include file.  Must be first.
#include <XSLT/XSLTDefinitions.hpp>

#include <map>
#include <set>
#include <vector>

#include <PlatformSupport/DOMStringHelper.hpp>

#include <XPath/NameSpace.hpp>
#include <XPath/XalanQName.hpp>

XALAN_CPP_NAMESPACE_BEGIN

class StylesheetConstructionContext;
class StylesheetExecutionContext;

class XALAN_XSLT_EXPORT NamespacesHandler
{
public:

	class PrefixChecker
	{
	public:

		PrefixChecker();

		virtual
		~PrefixChecker();

		virtual bool
		isActive(const XalanDOMString&	thePrefix) const = 0;
	};

	class XALAN_XSLT_EXPORT Namespace
	{
	public:

		Namespace() :
			m_prefix(&s_emptyString),
			m_uri(&s_emptyString)
		{
		}

		Namespace(
					const XalanDOMString&	prefix,
					const XalanDOMString&	uri) :
			m_prefix(&prefix),
			m_uri(&uri)
		{
		}

		/**
		 * Retrieve the prefix for namespace
		 *
		 * @return prefix string
		 */
		const XalanDOMString&
		getPrefix() const
		{
			assert(m_prefix != 0);

			return *m_prefix;
		}

		/**
		 * Set the prefix for namespace
		 *
		 * @param prefix The new prefix value
		 */
		void
		setPrefix(const XalanDOMString&		prefix)
		{
			m_prefix = &prefix;
		}

		/**
		 * Retrieve the URI for namespace
		 *
		 * @return URI string
		 */
		const XalanDOMString&
		getURI() const
		{
			assert(m_uri != 0);

			return *m_uri;
		}

		/**
		 * Set the URI for namespace
		 *
		 * @param uri The new uri value
		 */
		void
		setURI(const XalanDOMString&	uri)
		{
			m_uri = &uri;
		}

	protected:

		static const XalanDOMString		s_emptyString;

	private:

		const XalanDOMString*	m_prefix;

		const XalanDOMString*	m_uri;
	};

	class NamespaceExtended : public Namespace
	{
	public:

		NamespaceExtended() :
			Namespace(),
			m_resultAttributeName(&s_emptyString)
		{
		}

		NamespaceExtended(
					const XalanDOMString&	prefix,
					const XalanDOMString&	uri) :
			Namespace(prefix, uri),
			m_resultAttributeName(&s_emptyString)
		{
		}

		/**
		 * Retrieve the name of the result attribute.
		 *
		 * @return name string
		 */
		const XalanDOMString&
		getResultAttributeName() const
		{
			assert(m_resultAttributeName != 0);

			return *m_resultAttributeName;
		}

		/**
		 * Set the name of the result attribute.
		 *
		 * @param name The new name value
		 */
		void
		setResultAttributeName(const XalanDOMString&	name)
		{
			m_resultAttributeName = &name;
		}

	private:

		const XalanDOMString*	m_resultAttributeName;
	};

	typedef XalanQName::NamespaceVectorType				NamespaceVectorType;
	typedef XalanQName::NamespacesStackType				NamespacesStackType;

#if defined(XALAN_NO_STD_NAMESPACE)
	typedef vector<Namespace>							NamespacesVectorType;

	typedef vector<NamespaceExtended>					NamespaceExtendedVectorType;

	typedef map<const XalanDOMString*,
				const XalanDOMString*,
				DOMStringPointerLessThanFunction>		ExcludedResultPrefixesMapType;

	typedef map<const XalanDOMString*,
				NamespaceExtended,
				DOMStringPointerLessThanFunction>		NamespacesMapType;

	typedef map<const XalanDOMString*,
				const XalanDOMString*,
				DOMStringPointerLessThanFunction>		NamespaceAliasesMapType;

	typedef vector<const XalanDOMString*>				XalanDOMStringPointerVectorType;
#else
	typedef std::vector<Namespace>						NamespacesVectorType;

	typedef std::vector<NamespaceExtended>				NamespaceExtendedVectorType;

	typedef std::map<const XalanDOMString*,
					 const XalanDOMString*,
					 DOMStringPointerLessThanFunction>	ExcludedResultPrefixesMapType;

	typedef std::map<const XalanDOMString*,
					 NamespaceExtended,
					 DOMStringPointerLessThanFunction>	NamespacesMapType;

	typedef std::map<const XalanDOMString*,
					 const XalanDOMString*,
					 DOMStringPointerLessThanFunction>	NamespaceAliasesMapType;

	typedef std::vector<const XalanDOMString*>			XalanDOMStringPointerVectorType;
#endif

	/**
	 * Create a default, empty instance.
	 */
	explicit
	NamespacesHandler();

	/**
	 * Create an instance namespace handler using the
	 * current namespaces in effect.
	 *
	 * @param theConstructionContext The current construction context.
	 * @param stylesheetNamespacesHandler The stylesheet's handler.
	 * @param theCurrentNamespaces The stack of active namespace declarations.
	 * @param theXSLTNamespaceURI The namespace URI for XSLT.
	 */
	NamespacesHandler(
			StylesheetConstructionContext&	theConstructionContext,
			const NamespacesHandler&		stylesheetNamespacesHandler,
			const NamespacesStackType&		theCurrentNamespaces,
			const XalanDOMString&			theXSLTNamespaceURI);

	~NamespacesHandler();

	/**
	 * Process an exclude-result-prefixes attribute.
	 *
	 * @param theConstructionContext The current construction context.
	 * @param theValue The attribute's value.
	 * @param theCurrentNamespaces The stack of active namespace declarations.
	 */
	void
	processExcludeResultPrefixes(
			StylesheetConstructionContext&	theConstructionContext,
			const XalanDOMChar*				theValue,
			const NamespacesStackType&		theCurrentNamespaces);

	/**
	 * Process an extension-element-prefixes attribute.
	 *
	 * @param theConstructionContext The current construction context.
	 * @param theValue The attribute's value.
	 * @param theCurrentNamespaces The stack of active namespace declarations.
	 */
	void
	processExtensionElementPrefixes(
			StylesheetConstructionContext&	theConstructionContext,
			const XalanDOMChar*				theValue,
			const NamespacesStackType&		theCurrentNamespaces);

	/**
	 * Notify the instance that the stylesheet is fully constructed.
	 *
	 * @param theConstructionContext The current construction context.
	 * @param fProcessNamespaceAliases If true, process any namespace aliases
	 * @param theElementName The name of the owning element.
	 * @param parentNamespacesHandler The parent handler, if any.
	 * @param prefixChecker A pointer to a PrefixChecker instance to use, if any.
	 */
	void
	postConstruction(
			StylesheetConstructionContext&	theConstructionContext,
			bool							fProcessNamespaceAliases = true,
			const XalanDOMString&			theElementName = XalanDOMString(),
			const NamespacesHandler*		parentNamespacesHandler = 0,
			const PrefixChecker*			prefixChecker = 0);

	NamespacesHandler&
	operator=(const NamespacesHandler&	theRHS);

	/**
	 * Determine of a given namespace should be excluded.
	 *
	 * @param theXSLTNamespaceURI The namespace URI for XSLT.
	 * @param theURI The namespace URI.
	 * @return true of the namespace should be excluded, false if not.
	 */
	bool
	shouldExcludeResultNamespaceNode(
			const XalanDOMString&	theXSLTNamespaceURI,
			const XalanDOMString&	theURI) const;

	/**
	 * Add a URI as an extension namespace prefixes.
	 *
	 * @param theConstructionContext The current construction context.
	 * @param theURI The namespace URI.
	 */
	void
	addExtensionNamespaceURI(
			StylesheetConstructionContext&	theConstructionContext,
			const XalanDOMString&	theURI);

	/**
	 * Get the namespace URI for the given prefix.
	 *
	 * @param thePrefix The namespace prefix.
	 * @return The namespace URI
	 */
	const XalanDOMString*
	getNamespace(const XalanDOMString&	thePrefix) const;

	/**
	 * Get the namespace alias URI for the given namespace.
	 *
	 * @param theStylesheetNamespace The namespace as declared in the stylesheet.
	 * @return The namespace alias URI
	 */
	const XalanDOMString*
	getNamespaceAlias(const XalanDOMString&		theStylesheetNamespace) const;

	/**
	 * Set the namespace alias URI for the given namespace.
	 *
	 * @param theConstructionContext The current construction context.
	 * @param theStylesheetNamespace The namespace as declared in the stylesheet.
	 * @param theResultNamespace The namespace as it should appear in the result tree.
	 */
	void
	setNamespaceAlias(
			StylesheetConstructionContext&	theConstructionContext,
			const XalanDOMString&			theStylesheetNamespace,
			const XalanDOMString&			theResultNamespace);

	/**
	 * Copy the aliases from the given NamespacesHandler.
	 *
	 * @param parentNamespacesHandler The parent handler.
	 */
	void
	copyNamespaceAliases(const NamespacesHandler&	parentNamespacesHandler);

	/**
	 * Output the result tree namespace declarations.
	 *
	 * @param theExecutionContext The current execution context.
	 * @param supressDefault If true, any default namespace declaration will not be output.
	 */
	void
	outputResultNamespaces(
			StylesheetExecutionContext&		theExecutionContext,
			bool							supressDefault = false) const;

	/**
	 * Clear out the handler.
	 */
	void
	clear();

	/**
	 * Swap the contents of this instance with another.
	 *
	 * @param theOther The other instance.
	 */
	void
	swap(NamespacesHandler&		theOther);

	NamespacesMapType::size_type
	getNamespaceDeclarationsCount() const
	{
		return m_namespaceDeclarations.size();
	}

private:

	/**
	 * Create all of the result attribute names.
	 *
	 * @param theConstructionContext The current construction context.
	 */
	void
	createResultAttributeNames(StylesheetConstructionContext&	theConstructionContext);

	/**
	 * Process the exclude result prefix data.
	 *
	 * @param theConstructionContext The current construction context.
	 * @param theElementPrefix The prefix of the owning element.
	 * @param prefixChecker A pointer to a PrefixChecker instance to use, if any.
	 */
	void
	processExcludeResultPrefixes(
			StylesheetConstructionContext&	theConstructionContext,
			const XalanDOMString&			theElementPrefix,
			const PrefixChecker*			prefixChecker);

	/**
	 * Process the namespace aliases data.
	 */
	void
	processNamespaceAliases();

	/**
	 * Copy the contents of the supplied map
	 *
	 * @param theNamespaceAliases The map to copy.
	 */
	void
	copyNamespaceAliases(const NamespaceAliasesMapType&		theNamespaceAliases);

	/**
	 * Copy the contents of the supplied vector
	 *
	 * @param theExtensionNamespaceURIs The set to copy.
	 */
	void
	copyExtensionNamespaceURIs(const XalanDOMStringPointerVectorType&	theExtensionNamespaceURIs);

	/**
	 * Copy the contents of the supplied vector
	 *
	 * @param theExcludeResultPrefixes The vector to copy.
	 */
	void
	copyExcludeResultPrefixes(const NamespacesVectorType&	theExcludeResultPrefixes);

	/**
	 * Determine if a given namespace should be excluded as a result of
	 * an exclude-result-prefixes declaration.
	 *
	 * @param theNamespaceURI The namespace URI to check.
	 * @return true if the namespace should be excluded, false if not.
	 */
	bool
	isExcludedNamespaceURI(const XalanDOMString&	theNamespaceURI) const;

	/**
	 * Determine if a given URI is an extension namespace URI
	 *
	 * @param theNamespaceURI The namespace URI to check.
	 * @return true if the namespace uri is an extension namespace URI, false if not.
	 */
	bool
	isExtensionNamespaceURI(const XalanDOMString&	theNamespaceURI) const
	{
		return findString(theNamespaceURI, m_extensionNamespaceURIs);
	}

	/**
	 * Determine if a given string is present in the vector
	 *
	 * @param theString The string to find.
	 * @return true if the string is present, false if not.
	 */
	static bool
	findString(
			const XalanDOMString&					theString,
			const XalanDOMStringPointerVectorType&	theVector);

	// Not implemented...
	bool
	operator==(const NamespacesHandler&) const;

	// Data members...
	NamespacesVectorType				m_excludedResultPrefixes;

	NamespaceExtendedVectorType			m_namespaceDeclarations;

	XalanDOMStringPointerVectorType		m_extensionNamespaceURIs;

	NamespaceAliasesMapType				m_namespaceAliases;
};

XALAN_CPP_NAMESPACE_END

#endif	// XALAN_NAMESPACESHANDLER_HEADER_GUARD
<|endoftext|>


<commit_before>#include <algorithm>
#include <cmath>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>

#include <popt.h>

#include "defs.hh"
#include "StringSet.hh"
#include "FactorEncoder.hh"
#include "Unigrams.hh"
#include "Bigrams.hh"

using namespace std;

void
assert_single_chars(map<string, flt_type> &vocab,
                    const map<string, flt_type> &chars,
                    flt_type val)
{
    for (auto it = chars.cbegin(); it != chars.cend(); ++it)
        if (vocab.find(it->first) == vocab.end())
            vocab[it->first] = val;
}

int main(int argc, char* argv[]) {

    int iter_amount = 10;
    int least_common = 0;
    int target_vocab_size = 30000;
    float cutoff_value = 0.0;
    flt_type one_char_min_lp = -25.0;
    string vocab_fname;
    string wordlist_fname;
    string msfg_fname;
    string transition_fname;

    // Popt documentation:
    // http://linux.die.net/man/3/popt
    // http://privatemisc.blogspot.fi/2012/12/popt-basic-example.html
    poptContext pc;
    struct poptOption po[] = {
        {"iter", 'i', POPT_ARG_INT, &iter_amount, 11001, NULL, "How many iterations"},
        {"least-common", 'l', POPT_ARG_INT, &least_common, 11001, NULL, "Remove least common strings"},
        {"vocab_size", 'g', POPT_ARG_INT, &target_vocab_size, 11007, NULL, "Target vocabulary size (stopping criterion)"},
        {"cutoff", 'u', POPT_ARG_FLOAT, &cutoff_value, 11001, NULL, "Cutoff value for each iteration"},
        POPT_AUTOHELP
        {NULL}
    };

    pc = poptGetContext(NULL, argc, (const char **)argv, po, 0);
    poptSetOtherOptionHelp(pc, "[INITIAL VOCABULARY] [WORDLIST] [MSFG_IN] [TRANSITIONS]");

    int val;
    while ((val = poptGetNextOpt(pc)) >= 0)
        continue;

    // poptGetNextOpt returns -1 when the final argument has been parsed
    // otherwise an error occured
    if (val != -1) {
        switch (val) {
        case POPT_ERROR_NOARG:
            cerr << "Argument missing for an option" << endl;
            exit(1);
        case POPT_ERROR_BADOPT:
            cerr << "Option's argument could not be parsed" << endl;
            exit(1);
        case POPT_ERROR_BADNUMBER:
        case POPT_ERROR_OVERFLOW:
            cerr << "Option could not be converted to number" << endl;
            exit(1);
        default:
            cerr << "Unknown error in option processing" << endl;
            exit(1);
        }
    }

    // Handle ARG part of command line
    if (poptPeekArg(pc) != NULL)
        vocab_fname.assign((char*)poptGetArg(pc));
    else {
        cerr << "Initial vocabulary file not set" << endl;
        exit(1);
    }

    if (poptPeekArg(pc) != NULL)
        wordlist_fname.assign((char*)poptGetArg(pc));
    else {
        cerr << "Wordlist file not set" << endl;
        exit(1);
    }

    if (poptPeekArg(pc) != NULL)
        msfg_fname.assign((char*)poptGetArg(pc));
    else {
        cerr << "Input MSFG file not set" << endl;
        exit(1);
    }

    if (poptPeekArg(pc) != NULL)
        transition_fname.assign((char*)poptGetArg(pc));
    else {
        cerr << "Transition file not set" << endl;
        exit(1);
    }

    cerr << "parameters, initial vocabulary: " << vocab_fname << endl;
    cerr << "parameters, wordlist: " << wordlist_fname << endl;
    cerr << "parameters, msfg: " << msfg_fname << endl;
    cerr << "parameters, transitions: " << transition_fname << endl;
    cerr << "parameters, cutoff: " << setprecision(15) << cutoff_value << endl;
    cerr << "parameters, iterations: " << iter_amount << endl;
    cerr << "parameters, target vocab size: " << target_vocab_size << endl;
    cerr << "parameters, least common subwords to remove: " << least_common << endl;

    int maxlen, word_maxlen;
    map<string, flt_type> all_chars;
    map<string, flt_type> vocab;
    map<string, flt_type> freqs;
    map<string, flt_type> words;

    cerr << "Reading vocabulary " << vocab_fname << endl;
    int retval = Unigrams::read_vocab(vocab_fname, vocab, maxlen);
    if (retval < 0) {
        cerr << "something went wrong reading vocabulary" << endl;
        exit(0);
    }
    cerr << "\t" << "size: " << vocab.size() << endl;
    cerr << "\t" << "maximum string length: " << maxlen << endl;
    for (auto it = vocab.cbegin(); it != vocab.end(); ++it)
        if (it->first.length() == 1)
            all_chars[it->first] = 0.0;

    cerr << "Reading word list " << wordlist_fname << endl;
    retval = Unigrams::read_vocab(wordlist_fname, words, word_maxlen);
    if (retval < 0) {
        cerr << "something went wrong reading word list" << endl;
        exit(0);
    }
    cerr << "\t" << "wordlist size: " << words.size() << endl;
    cerr << "\t" << "maximum word length: " << word_maxlen << endl;

    Unigrams ug;
    ug.set_segmentation_method(forward_backward);

    cerr << "Initial cutoff" << endl;
    ug.resegment_words(words, vocab, freqs);
    flt_type densum = ug.get_sum(freqs);
    flt_type cost = ug.get_cost(freqs, densum);
    cerr << "unigram cost without word end symbols: " << cost << endl;

    ug.cutoff(freqs, (flt_type)cutoff_value);
    cerr << "\tcutoff: " << cutoff_value << "\t" << "vocabulary size: " << freqs.size() << endl;
    vocab = freqs;
    densum = ug.get_sum(vocab);
    ug.freqs_to_logprobs(vocab, densum);
    assert_single_chars(vocab, all_chars, one_char_min_lp);

    string start_end_symbol("*");
    StringSet ss_vocab(vocab);
    map<string, FactorGraph*> fg_words;
    MultiStringFactorGraph msfg(start_end_symbol);
    msfg.read(msfg_fname);
    transitions_t transitions;
    transitions_t trans_stats;
    map<string, flt_type> unigram_stats;
    vocab[start_end_symbol] = 0.0;
    flt_type lp = 0.0;

    // Initial segmentation using unigram model
    assign_scores(vocab, msfg);
    lp = Bigrams::collect_trans_stats(words, msfg, trans_stats, unigram_stats);

    // Unigram cost with word end markers
    densum = ug.get_sum(unigram_stats);
    cost = ug.get_cost(unigram_stats, densum);
    cerr << "unigram cost with word end symbols: " << cost << endl;

    // Initial bigram cost
    transitions = trans_stats;
    Bigrams::normalize(transitions);
    cerr << "bigram cost: " << lp << endl;
    cerr << "\tamount of transitions: " << Bigrams::transition_count(transitions) << endl;
    cerr << "\tvocab size: " << unigram_stats.size() << endl;
    int co_removed = Bigrams::cutoff(unigram_stats, cutoff_value, transitions, msfg);
    cerr << "\tremoved by cutoff: " << co_removed << endl;

    assign_scores(transitions, msfg);

    // Re-estimate using bigram stats
    for (int i=0; i<iter_amount; i++) {

        flt_type lp = Bigrams::collect_trans_stats(words, msfg, trans_stats, unigram_stats);
        int vocab_size = unigram_stats.size();
        cerr << "bigram cost: " << lp << endl;
        cerr << "\tamount of transitions: " << Bigrams::transition_count(transitions) << endl;
        cerr << "\tvocab size: " << vocab_size << endl;

        Bigrams::copy_transitions(trans_stats, transitions);
        if (least_common > 0) {
            int curr_least_common = least_common + ((vocab_size-least_common) % 1000);
            int lc_removed = Bigrams::remove_least_common(unigram_stats, curr_least_common, transitions, msfg);
            cerr << "\tremoved " << lc_removed << " least common subwords" << endl;
        }
        Bigrams::normalize(transitions);
        vocab_size = unigram_stats.size();

        // Write temp transitions
        ostringstream transitions_temp;
        transitions_temp << "transitions.iter" << i+1 << ".bz2";
        cerr << "\twriting to: " << transitions_temp.str() << endl;
        Bigrams::write_transitions(transitions, transitions_temp.str());

        if  (vocab_size < target_vocab_size) break;
    }

    // Write transitions
    Bigrams::write_transitions(transitions, transition_fname);

    exit(1);
}
<commit_msg>First real version of g2g.<commit_after>#include <algorithm>
#include <cmath>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>

#include <popt.h>

#include "defs.hh"
#include "StringSet.hh"
#include "FactorEncoder.hh"
#include "Unigrams.hh"
#include "Bigrams.hh"

using namespace std;

void
assert_single_chars(map<string, flt_type> &vocab,
                    const map<string, flt_type> &chars,
                    flt_type val)
{
    for (auto it = chars.cbegin(); it != chars.cend(); ++it)
        if (vocab.find(it->first) == vocab.end())
            vocab[it->first] = val;
}

int main(int argc, char* argv[]) {

    float cutoff_value = 0.0;
    int n_candidates_per_iter = 5000;
    int max_removals_per_iter = 5000;
    int target_vocab_size = 30000;
    flt_type one_char_min_lp = -25.0;
    string vocab_fname;
    string wordlist_fname;
    string msfg_fname;
    string transition_fname;

    // Popt documentation:
    // http://linux.die.net/man/3/popt
    // http://privatemisc.blogspot.fi/2012/12/popt-basic-example.html
    poptContext pc;
    struct poptOption po[] = {
        {"candidates", 'c', POPT_ARG_INT, &n_candidates_per_iter, 11002, NULL, "Number of candidate subwords to try to remove per iteration"},
        {"max_removals", 'a', POPT_ARG_INT, &max_removals_per_iter, 11003, NULL, "Maximum number of removals per iteration"},
        {"cutoff", 'u', POPT_ARG_FLOAT, &cutoff_value, 11001, NULL, "Cutoff value for each iteration"},
        {"vocab_size", 'g', POPT_ARG_INT, &target_vocab_size, 11007, NULL, "Target vocabulary size (stopping criterion)"},
        POPT_AUTOHELP
        {NULL}
    };

    pc = poptGetContext(NULL, argc, (const char **)argv, po, 0);
    poptSetOtherOptionHelp(pc, "[INITIAL VOCABULARY] [WORDLIST] [MSFG_IN] [TRANSITIONS]");

    int val;
    while ((val = poptGetNextOpt(pc)) >= 0)
        continue;

    // poptGetNextOpt returns -1 when the final argument has been parsed
    // otherwise an error occured
    if (val != -1) {
        switch (val) {
        case POPT_ERROR_NOARG:
            cerr << "Argument missing for an option" << endl;
            exit(1);
        case POPT_ERROR_BADOPT:
            cerr << "Option's argument could not be parsed" << endl;
            exit(1);
        case POPT_ERROR_BADNUMBER:
        case POPT_ERROR_OVERFLOW:
            cerr << "Option could not be converted to number" << endl;
            exit(1);
        default:
            cerr << "Unknown error in option processing" << endl;
            exit(1);
        }
    }

    // Handle ARG part of command line
    if (poptPeekArg(pc) != NULL)
        vocab_fname.assign((char*)poptGetArg(pc));
    else {
        cerr << "Initial vocabulary file not set" << endl;
        exit(1);
    }

    if (poptPeekArg(pc) != NULL)
        wordlist_fname.assign((char*)poptGetArg(pc));
    else {
        cerr << "Wordlist file not set" << endl;
        exit(1);
    }

    if (poptPeekArg(pc) != NULL)
        msfg_fname.assign((char*)poptGetArg(pc));
    else {
        cerr << "Input MSFG file not set" << endl;
        exit(1);
    }

    if (poptPeekArg(pc) != NULL)
        transition_fname.assign((char*)poptGetArg(pc));
    else {
        cerr << "Transition file not set" << endl;
        exit(1);
    }

    cerr << "parameters, initial vocabulary: " << vocab_fname << endl;
    cerr << "parameters, wordlist: " << wordlist_fname << endl;
    cerr << "parameters, msfg: " << msfg_fname << endl;
    cerr << "parameters, transitions: " << transition_fname << endl;
    cerr << "parameters, candidates per iteration: " << n_candidates_per_iter << endl;
    cerr << "parameters, removals per iteration: " << max_removals_per_iter << endl;
    cerr << "parameters, cutoff: " << setprecision(15) << cutoff_value << endl;
    cerr << "parameters, target vocab size: " << target_vocab_size << endl;

    int maxlen, word_maxlen;
    map<string, flt_type> all_chars;
    map<string, flt_type> vocab;
    map<string, flt_type> freqs;
    map<string, flt_type> words;

    cerr << "Reading vocabulary " << vocab_fname << endl;
    int retval = Unigrams::read_vocab(vocab_fname, vocab, maxlen);
    if (retval < 0) {
        cerr << "something went wrong reading vocabulary" << endl;
        exit(0);
    }
    cerr << "\t" << "size: " << vocab.size() << endl;
    cerr << "\t" << "maximum string length: " << maxlen << endl;
    for (auto it = vocab.cbegin(); it != vocab.end(); ++it)
        if (it->first.length() == 1)
            all_chars[it->first] = 0.0;

    cerr << "Reading word list " << wordlist_fname << endl;
    retval = Unigrams::read_vocab(wordlist_fname, words, word_maxlen);
    if (retval < 0) {
        cerr << "something went wrong reading word list" << endl;
        exit(0);
    }
    cerr << "\t" << "wordlist size: " << words.size() << endl;
    cerr << "\t" << "maximum word length: " << word_maxlen << endl;

    Unigrams ug;
    ug.set_segmentation_method(forward_backward);

    cerr << "Initial cutoff" << endl;
    ug.resegment_words(words, vocab, freqs);
    flt_type densum = ug.get_sum(freqs);
    flt_type cost = ug.get_cost(freqs, densum);
    cerr << "unigram cost without word end symbols: " << cost << endl;

    ug.cutoff(freqs, (flt_type)cutoff_value);
    cerr << "\tcutoff: " << cutoff_value << "\t" << "vocabulary size: " << freqs.size() << endl;
    vocab = freqs;
    densum = ug.get_sum(vocab);
    ug.freqs_to_logprobs(vocab, densum);
    assert_single_chars(vocab, all_chars, one_char_min_lp);

    string start_end_symbol("*");
    StringSet ss_vocab(vocab);
    map<string, FactorGraph*> fg_words;
    MultiStringFactorGraph msfg(start_end_symbol);
    msfg.read(msfg_fname);
    transitions_t transitions;
    transitions_t trans_stats;
    map<string, flt_type> unigram_stats;
    vocab[start_end_symbol] = 0.0;
    flt_type lp = 0.0;

    // Initial segmentation using unigram model
    assign_scores(vocab, msfg);
    lp = Bigrams::collect_trans_stats(words, msfg, trans_stats, unigram_stats);

    // Unigram cost with word end markers
    densum = ug.get_sum(unigram_stats);
    cost = ug.get_cost(unigram_stats, densum);
    cerr << "unigram cost with word end symbols: " << cost << endl;

    // Initial bigram cost
    transitions = trans_stats;
    Bigrams::normalize(transitions);
    cerr << "bigram cost: " << lp << endl;
    cerr << "\tamount of transitions: " << Bigrams::transition_count(transitions) << endl;
    cerr << "\tvocab size: " << unigram_stats.size() << endl;
    int co_removed = Bigrams::cutoff(unigram_stats, cutoff_value, transitions, msfg);
    cerr << "\tremoved by cutoff: " << co_removed << endl;

    assign_scores(transitions, msfg);

    // Re-estimate using bigram stats
    int iteration = 1;
    while (true) {

        cerr << "Iteration " << iteration << endl;

        flt_type lp = Bigrams::collect_trans_stats(words, msfg, trans_stats, unigram_stats);
        Bigrams::copy_transitions(trans_stats, transitions);
        Bigrams::normalize(transitions);

        cerr << "\tbigram cost: " << lp << endl;
        cerr << "\tamount of transitions: " << Bigrams::transition_count(transitions) << endl;
        cerr << "\tvocab size: " << unigram_stats.size() << endl;

        // Get removal candidates based on unigram stats
        cerr << "\titializing removals .." << endl;
        vector<pair<string, flt_type> > sorted_stats;
        Unigrams::sort_vocab(unigram_stats, sorted_stats, false);
        map<string, flt_type> candidates;
        for (auto it = sorted_stats.begin(); it != sorted_stats.end(); ++it) {
            if (it->first.length() < 2) continue;
            candidates[it->first] = 0.0;
            if (candidates.size() >= n_candidates_per_iter) break;
        }

        // Score all candidates
        cerr << "\tranking removals .." << endl;
        map<string, set<string> > backpointers;
        Bigrams::get_backpointers(msfg, backpointers, 1);
        transitions_t reverse;
        Bigrams::reverse_transitions(transitions, reverse);
        int cidx = 0;
        for (auto it = candidates.begin(); it != candidates.end(); ++it) {
            transitions_t changes;
            set<string> words_to_resegment = backpointers.at(it->first);
            flt_type orig_score = likelihood(words, words_to_resegment, msfg);
            flt_type context_score = Bigrams::remove_string(reverse, it->first,
                                                            unigram_stats, transitions, changes);
            flt_type hypo_score = likelihood(words, words_to_resegment, msfg);
            it->second = hypo_score-orig_score + context_score;
            Bigrams::restore_string(transitions, changes);
            if (cidx % 1000 == 0) cout << "\tcandidate " << cidx << endl;
            cidx++;
        }

        // Remove least significant subwords
        vector<pair<string, flt_type> > sorted_scores;
        Unigrams::sort_vocab(candidates, sorted_scores, true);
        vector<string> to_remove;
        for (auto it = sorted_scores.begin(); it != sorted_scores.end(); ++it) {
            to_remove.push_back(it->first);
            if (to_remove.size() >= max_removals_per_iter) break;
        }
        Bigrams::remove_transitions(to_remove, transitions);
        for (int i=0; i<to_remove.size(); i++)
            msfg.remove_arcs(to_remove[i]);

        // Write temp transitions
        ostringstream transitions_temp;
        transitions_temp << "transitions.iter" << iteration << ".bz2";
        cerr << "\twriting to: " << transitions_temp.str() << endl;
        Bigrams::write_transitions(transitions, transitions_temp.str());

        if  (unigram_stats.size() <= target_vocab_size) break;
        iteration++;
    }

    // Write transitions
    Bigrams::write_transitions(transitions, transition_fname);

    exit(1);
}
<|endoftext|>


<commit_before>#include <QAction>
#include <QApplication>
#include <QBoxLayout>
#include <QTime>
#include <QTimer>

#include "base.h"
#include "dialog.h"
#include "dlog.h"
#include "menu.h"
#include "note.h"
#include "proj.h"
#include "term.h"
#include "tedit.h"
#include "svr.h"
#include "state.h"
#include "recent.h"

using namespace std;

Term *term;
Tedit *tedit;
int idewin=0;  // 0: term  1: note 2: note2

QString LastLaunch;
QTime LastLaunchTime;
QTimer *timer=0;

extern "C" void smact();

// ---------------------------------------------------------------------
OneWin::OneWin()
{
  note = new Note();
  split=new QSplitter(Qt::Vertical);
  split->addWidget(makeframe((QWidget *)note));
  split->addWidget(makeframe((QWidget *)term));
  QList<int> n;
  n << 0 << 1;
  //split->setSizes(n);
  QVBoxLayout *layout=new QVBoxLayout();
  layout->setContentsMargins(0,0,0,0);
  layout->addWidget(split);
  setLayout(layout);
  term->setFocus();
  show();
}

// ---------------------------------------------------------------------
void OneWin::closeEvent(QCloseEvent *event)
{
  term->filequit();
  event->ignore();
}

// ---------------------------------------------------------------------
QFrame *OneWin::makeframe(QWidget *w)
{
  QFrame *f=new QFrame();
  //f->setFrameStyle(QFrame::Panel | QFrame::Raised);
  f->setFrameStyle(QFrame::StyledPanel);
  QVBoxLayout *b=new QVBoxLayout();
  b->setContentsMargins(0,0,0,0);
  b->addWidget(w);
  f->setLayout(b);
  return f;
}

// ---------------------------------------------------------------------
Term::Term()
{
  QVBoxLayout *layout=new QVBoxLayout;
  layout->setContentsMargins(layout->contentsMargins());
  layout->setSpacing(0);
  menuBar = new Menu();
  tedit = new Tedit;
  layout->addWidget(menuBar);
  layout->addWidget(tedit);
  setWindowTitle("Term");
  menuBar->createActions();
  menuBar->createMenus("term");
  setLayout(layout);
  timer=new QTimer;
  connect(timer, SIGNAL(timeout()),this,SLOT(systimer()));
  QMetaObject::connectSlotsByName(this);
}

// ---------------------------------------------------------------------
void Term::activate()
{
  activateWindow();
  raise();
  tedit->setFocus();
}

// ---------------------------------------------------------------------
void Term::closeEvent(QCloseEvent *event)
{
  filequit();
  event->ignore();
}

// ---------------------------------------------------------------------
bool Term::filequit()
{
  dlog_write();
#ifdef Q_OS_ANDROID
  state_quit();
  QApplication::quit();
  return true;
#else
  if (note && (!note->saveall())) return false;
  if (note2 && (!note2->saveall())) return false;
  if ((!config.ConfirmClose) ||
      queryOK("Term","OK to exit " + config.Lang + "?")) {
    state_quit();
    QApplication::quit();
    return true;
  } else
    return false;
#endif
}

// ---------------------------------------------------------------------
// this run after configs read...
void Term::fini()
{
  menuBar->createMenus_fini("term");
  move(config.TermPos[0],config.TermPos[1]);
  resize(config.TermPos[2],config.TermPos[3]);
  tedit->setFont(config.Font);
  QPalette p = palette();
  p.setColor(QPalette::Active, QPalette::Base, config.TermBack.color);
  p.setColor(QPalette::Inactive, QPalette::Base, config.TermBack.color);
  p.setColor(QPalette::Text, config.TermFore.color);
  tedit->setPalette(p);
  QString s=config.BinPath.filePath("icons/jgreen.png");
  setWindowIcon(QIcon(s));
  if (config.TermSyntaxHighlight)
    highlight(tedit->document());
  tedit->setprompt();
  if (config.SingleWin)
    new OneWin();
  else if (ShowIde)
    show();
}

// ---------------------------------------------------------------------
void Term::keyPressEvent(QKeyEvent *event)
{
  switch (event->key()) {
#ifdef JQT
#ifdef Q_OS_ANDROID
  case 16777220:
    event->accept();
    filequit();
    break;
#endif
  case Qt::Key_Escape:
    if (config.EscClose) {
      if (!filequit())
        event->accept();
    }
    break;
#endif
  default:
    QWidget::keyPressEvent(event);
  }
}

// ---------------------------------------------------------------------
// bug in Qt - this gets called twice, so need to check time...
void Term::launchpad_triggered(QAction *a)
{
  QString s=a->objectName();

  s=s.mid(config.LaunchPadPrefix.size());
  QTime t=QTime::currentTime();
  if (LastLaunch==s && LastLaunchTime.secsTo(t)<2) return;
  LastLaunch=s;
  LastLaunchTime=t;
  int i=config.LaunchPadKeys.indexOf(s);

  if (i<0) return;
  tedit->loadscript(config.LaunchPadValues.at(i),false);
}

// ---------------------------------------------------------------------
void Term::load(QString s, bool d)
{
  tedit->docmdx(var_load(s,d));
}

// ---------------------------------------------------------------------
void Term::pacman()
{
  var_cmd("require 'pacman ~addons/ide/qt/pacman.ijs'");
  var_cmd("runpacman_jpacman_ 0");
}

// ---------------------------------------------------------------------
void Term::projectenable()
{
  bool b=project.Id.size()>0;
  menuBar->runprojectAct->setEnabled(b);
  menuBar->projectcloseAct->setEnabled(b);
}

// ---------------------------------------------------------------------
void Term::resizeEvent(QResizeEvent *event)
{
  tedit->setresized(0);
  QWidget::resizeEvent(event);
}

// ---------------------------------------------------------------------
void Term::systimer()
{
  var_cmd("(i.0 0)\"_ sys_timer_z_$0");
}

// ---------------------------------------------------------------------
void Term::vieweditor()
{
  if (note) {
    note->activate();
#ifdef Q_OS_ANDROID
    term->setVisible(false);
    note->activateWindow();
    note->raise();
    note->repaint();
#endif
  } else {
    note = new Note();
    if (recent.ProjectOpen)
      note->projectopen(true);
    note->show();
#ifdef Q_OS_ANDROID
    term->setVisible(false);
    note->activateWindow();
    note->raise();
    note->repaint();
#endif
  }
  idewin=1;
}

// ---------------------------------------------------------------------
void smact()
{
  if (!term->isVisible()) return;
  term->activateWindow();
  term->raise();
  term->repaint();
  idewin=0;
}
<commit_msg>fix for msvc<commit_after>#include <QAction>
#include <QApplication>
#include <QBoxLayout>
#include <QTime>
#include <QTimer>

#include "base.h"
#include "dialog.h"
#include "dlog.h"
#include "menu.h"
#include "note.h"
#include "proj.h"
#include "term.h"
#include "tedit.h"
#include "svr.h"
#include "state.h"
#include "recent.h"

using namespace std;

Term *term;
Tedit *tedit;
int idewin=0;  // 0: term  1: note 2: note2

QString LastLaunch;
QTime LastLaunchTime;
QTimer *timer=0;

extern "C" Dllexport void smact();

// ---------------------------------------------------------------------
OneWin::OneWin()
{
  note = new Note();
  split=new QSplitter(Qt::Vertical);
  split->addWidget(makeframe((QWidget *)note));
  split->addWidget(makeframe((QWidget *)term));
  QList<int> n;
  n << 0 << 1;
  //split->setSizes(n);
  QVBoxLayout *layout=new QVBoxLayout();
  layout->setContentsMargins(0,0,0,0);
  layout->addWidget(split);
  setLayout(layout);
  term->setFocus();
  show();
}

// ---------------------------------------------------------------------
void OneWin::closeEvent(QCloseEvent *event)
{
  term->filequit();
  event->ignore();
}

// ---------------------------------------------------------------------
QFrame *OneWin::makeframe(QWidget *w)
{
  QFrame *f=new QFrame();
  //f->setFrameStyle(QFrame::Panel | QFrame::Raised);
  f->setFrameStyle(QFrame::StyledPanel);
  QVBoxLayout *b=new QVBoxLayout();
  b->setContentsMargins(0,0,0,0);
  b->addWidget(w);
  f->setLayout(b);
  return f;
}

// ---------------------------------------------------------------------
Term::Term()
{
  QVBoxLayout *layout=new QVBoxLayout;
  layout->setContentsMargins(layout->contentsMargins());
  layout->setSpacing(0);
  menuBar = new Menu();
  tedit = new Tedit;
  layout->addWidget(menuBar);
  layout->addWidget(tedit);
  setWindowTitle("Term");
  menuBar->createActions();
  menuBar->createMenus("term");
  setLayout(layout);
  timer=new QTimer;
  connect(timer, SIGNAL(timeout()),this,SLOT(systimer()));
  QMetaObject::connectSlotsByName(this);
}

// ---------------------------------------------------------------------
void Term::activate()
{
  activateWindow();
  raise();
  tedit->setFocus();
}

// ---------------------------------------------------------------------
void Term::closeEvent(QCloseEvent *event)
{
  filequit();
  event->ignore();
}

// ---------------------------------------------------------------------
bool Term::filequit()
{
  dlog_write();
#ifdef Q_OS_ANDROID
  state_quit();
  QApplication::quit();
  return true;
#else
  if (note && (!note->saveall())) return false;
  if (note2 && (!note2->saveall())) return false;
  if ((!config.ConfirmClose) ||
      queryOK("Term","OK to exit " + config.Lang + "?")) {
    state_quit();
    QApplication::quit();
    return true;
  } else
    return false;
#endif
}

// ---------------------------------------------------------------------
// this run after configs read...
void Term::fini()
{
  menuBar->createMenus_fini("term");
  move(config.TermPos[0],config.TermPos[1]);
  resize(config.TermPos[2],config.TermPos[3]);
  tedit->setFont(config.Font);
  QPalette p = palette();
  p.setColor(QPalette::Active, QPalette::Base, config.TermBack.color);
  p.setColor(QPalette::Inactive, QPalette::Base, config.TermBack.color);
  p.setColor(QPalette::Text, config.TermFore.color);
  tedit->setPalette(p);
  QString s=config.BinPath.filePath("icons/jgreen.png");
  setWindowIcon(QIcon(s));
  if (config.TermSyntaxHighlight)
    highlight(tedit->document());
  tedit->setprompt();
  if (config.SingleWin)
    new OneWin();
  else if (ShowIde)
    show();
}

// ---------------------------------------------------------------------
void Term::keyPressEvent(QKeyEvent *event)
{
  switch (event->key()) {
#ifdef JQT
#ifdef Q_OS_ANDROID
  case 16777220:
    event->accept();
    filequit();
    break;
#endif
  case Qt::Key_Escape:
    if (config.EscClose) {
      if (!filequit())
        event->accept();
    }
    break;
#endif
  default:
    QWidget::keyPressEvent(event);
  }
}

// ---------------------------------------------------------------------
// bug in Qt - this gets called twice, so need to check time...
void Term::launchpad_triggered(QAction *a)
{
  QString s=a->objectName();

  s=s.mid(config.LaunchPadPrefix.size());
  QTime t=QTime::currentTime();
  if (LastLaunch==s && LastLaunchTime.secsTo(t)<2) return;
  LastLaunch=s;
  LastLaunchTime=t;
  int i=config.LaunchPadKeys.indexOf(s);

  if (i<0) return;
  tedit->loadscript(config.LaunchPadValues.at(i),false);
}

// ---------------------------------------------------------------------
void Term::load(QString s, bool d)
{
  tedit->docmdx(var_load(s,d));
}

// ---------------------------------------------------------------------
void Term::pacman()
{
  var_cmd("require 'pacman ~addons/ide/qt/pacman.ijs'");
  var_cmd("runpacman_jpacman_ 0");
}

// ---------------------------------------------------------------------
void Term::projectenable()
{
  bool b=project.Id.size()>0;
  menuBar->runprojectAct->setEnabled(b);
  menuBar->projectcloseAct->setEnabled(b);
}

// ---------------------------------------------------------------------
void Term::resizeEvent(QResizeEvent *event)
{
  tedit->setresized(0);
  QWidget::resizeEvent(event);
}

// ---------------------------------------------------------------------
void Term::systimer()
{
  var_cmd("(i.0 0)\"_ sys_timer_z_$0");
}

// ---------------------------------------------------------------------
void Term::vieweditor()
{
  if (note) {
    note->activate();
#ifdef Q_OS_ANDROID
    term->setVisible(false);
    note->activateWindow();
    note->raise();
    note->repaint();
#endif
  } else {
    note = new Note();
    if (recent.ProjectOpen)
      note->projectopen(true);
    note->show();
#ifdef Q_OS_ANDROID
    term->setVisible(false);
    note->activateWindow();
    note->raise();
    note->repaint();
#endif
  }
  idewin=1;
}

// ---------------------------------------------------------------------
void smact()
{
  if (!term->isVisible()) return;
  term->activateWindow();
  term->raise();
  term->repaint();
  idewin=0;
}
<|endoftext|>


<commit_before>
#include "antsUtilities.h"
#include <algorithm>

#include <stdio.h>

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

#include "itkResampleImageFilter.h"

#include "itkConstantBoundaryCondition.h"
#include "itkIdentityTransform.h"
#include "itkBSplineInterpolateImageFunction.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkGaussianInterpolateImageFunction.h"
#include "itkNearestNeighborInterpolateImageFunction.h"
#include "itkWindowedSincInterpolateImageFunction.h"

#include <string>
#include <vector>

namespace ants
{

template <unsigned int ImageDimension>
int ResampleImage( int argc, char *argv[] )
{
  typedef double                                RealType;
  typedef double                                PixelType;
  typedef itk::Image<PixelType, ImageDimension> ImageType;

  typedef itk::ImageFileReader<ImageType> ReaderType;
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[2] );
  reader->Update();

  typedef itk::IdentityTransform<RealType, ImageDimension> TransformType;
  typename TransformType::Pointer transform = TransformType::New();
  transform->SetIdentity();

  typedef itk::LinearInterpolateImageFunction<ImageType, RealType>
    LinearInterpolatorType;
  typename LinearInterpolatorType::Pointer interpolator
    = LinearInterpolatorType::New();
  interpolator->SetInputImage( reader->GetOutput() );

  typedef itk::NearestNeighborInterpolateImageFunction<ImageType, RealType>
    NearestNeighborInterpolatorType;
  typename NearestNeighborInterpolatorType::Pointer nn_interpolator
    = NearestNeighborInterpolatorType::New();
  nn_interpolator->SetInputImage( reader->GetOutput() );

  typedef itk::BSplineInterpolateImageFunction<ImageType, RealType>
    BSplineInterpolatorType;
  typename BSplineInterpolatorType::Pointer bs_interpolator
    = BSplineInterpolatorType::New();
  bs_interpolator->SetInputImage( reader->GetOutput() );

  typedef itk::GaussianInterpolateImageFunction<ImageType, RealType>
    GaussianInterpolatorType;
  typename GaussianInterpolatorType::Pointer g_interpolator
    = GaussianInterpolatorType::New();
  g_interpolator->SetInputImage( reader->GetOutput() );

  typedef itk::WindowedSincInterpolateImageFunction<ImageType, 3> HammingInterpolatorType;
  typename HammingInterpolatorType::Pointer sh_interpolator = HammingInterpolatorType::New();
  sh_interpolator->SetInputImage( reader->GetOutput() );

  typedef itk::WindowedSincInterpolateImageFunction<ImageType, 3,
                                                    itk::Function::CosineWindowFunction<3> > Sinc1InterpolatorType;
  typename Sinc1InterpolatorType::Pointer sc_interpolator = Sinc1InterpolatorType::New();
  sc_interpolator->SetInputImage( reader->GetOutput() );

  typedef itk::WindowedSincInterpolateImageFunction<ImageType, 3,
                                                    itk::Function::WelchWindowFunction<3> > Sinc2InterpolatorType;
  typename Sinc2InterpolatorType::Pointer sw_interpolator = Sinc2InterpolatorType::New();
  sw_interpolator->SetInputImage( reader->GetOutput() );

  typedef itk::WindowedSincInterpolateImageFunction<ImageType, 3,
                                                    itk::Function::LanczosWindowFunction<3> > Sinc3InterpolatorType;
  typename Sinc3InterpolatorType::Pointer sl_interpolator = Sinc3InterpolatorType::New();
  sl_interpolator->SetInputImage( reader->GetOutput() );

  typename Sinc3InterpolatorType::Pointer sb_interpolator = Sinc3InterpolatorType::New();
  sb_interpolator->SetInputImage( reader->GetOutput() );

  typedef itk::ResampleImageFilter<ImageType, ImageType, RealType> ResamplerType;
  typename ResamplerType::Pointer resampler = ResamplerType::New();
  typename ResamplerType::SpacingType spacing;
  typename ResamplerType::SizeType size;

  std::vector<RealType> sp = ConvertVector<RealType>( std::string( argv[4] ) );

  if( argc <= 5 || atoi( argv[5] ) == 0 )
    {
    if( sp.size() == 1 )
      {
      spacing.Fill( sp[0] );
      }
    else if( sp.size() == ImageDimension )
      {
      for( unsigned int d = 0; d < ImageDimension; d++ )
        {
        spacing[d] = sp[d];
        }
      }
    else
      {
      std::cout << "Invalid spacing." << std::endl;
      }
    for( unsigned int i = 0; i < ImageDimension; i++ )
      {
      RealType spacing_old = reader->GetOutput()->GetSpacing()[i];
      RealType size_old = reader->GetOutput()->GetLargestPossibleRegion().GetSize()[i];
      size[i] = static_cast<int>( ( spacing_old * size_old ) / spacing[i] + 0.5 );
      }
    }
  else
    {
    if( sp.size() == 1 )
      {
      size.Fill( static_cast<unsigned int>( sp[0] ) );
      }
    else if( sp.size() == ImageDimension )
      {
      for( unsigned int d = 0; d < ImageDimension; d++ )
        {
        size[d] = static_cast<unsigned int>( sp[d] );
        }
      }
    else
      {
      std::cout << "Invalid size." << std::endl;
      }
    for( unsigned int i = 0; i < ImageDimension; i++ )
      {
      RealType spacing_old = reader->GetOutput()->GetSpacing()[i];
      RealType size_old = reader->GetOutput()->GetLargestPossibleRegion().GetSize()[i];
      spacing[i] = spacing_old * static_cast<float>( size_old - 1.0 )
        / static_cast<float>( size[i] - 1.0 );
      }
    }

  char arg7 = '\0';
  if( argc > 7 )
    {
    arg7 = *argv[7];
    }

  resampler->SetTransform( transform );
  resampler->SetInterpolator( interpolator );
  if( argc > 6 && atoi( argv[6] ) )
    {
    switch( atoi( argv[6] ) )
      {
      case 0: default:
        {
        resampler->SetInterpolator( interpolator );
        }
        break;
      case 1:
        {
        resampler->SetInterpolator( nn_interpolator );
        }
        break;
      case 2:
        {
        double sigma[ImageDimension];
        for( unsigned int d = 0; d < ImageDimension; d++ )
          {
          sigma[d] = reader->GetOutput()->GetSpacing()[d];
          }
        double alpha = 1.0;

        if( argc > 7 )
          {
          std::vector<RealType> sg = ConvertVector<RealType>( std::string( argv[7] ) );
          for( unsigned int d = 0; d < ImageDimension; d++ )
            {
            sigma[d] = sg[d];
            }
          }
        if( argc > 8 )
          {
          alpha = static_cast<double>( atof( argv[8] ) );
          }
        g_interpolator->SetParameters( sigma, alpha );

        resampler->SetInterpolator( g_interpolator );
        }
        break;
      case 3:
        {
        switch( arg7 )
          {
          case 'h': default:
            {
            resampler->SetInterpolator( sh_interpolator );
            }
            break;
          case 'c':
            {
            resampler->SetInterpolator( sc_interpolator );
            }
            break;
          case 'l':
            {
            resampler->SetInterpolator( sl_interpolator );
            }
            break;
          case 'w':
            {
            resampler->SetInterpolator( sw_interpolator );
            }
            break;
          case 'b':
            {
            resampler->SetInterpolator( sb_interpolator );
            }
            break;
          }
        }
      case 4:
        {
        if( argc > 7 && atoi( argv[7] ) >= 0 && atoi( argv[7] ) <= 5 )
          {
          bs_interpolator->SetSplineOrder( atoi( argv[7] ) );
          }
        else
          {
          bs_interpolator->SetSplineOrder( 3 );
          }
        resampler->SetInterpolator( bs_interpolator );
        }
        break;
      }
    }
  resampler->SetInput( reader->GetOutput() );
  resampler->SetSize( size );
  resampler->SetOutputOrigin( reader->GetOutput()->GetOrigin() );
  resampler->SetOutputDirection( reader->GetOutput()->GetDirection() );
  resampler->SetOutputSpacing( spacing );
  resampler->SetDefaultPixelValue( 0 );
  resampler->Update();

  typedef itk::ImageFileWriter<ImageType> WriterType;
  typename WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( argv[3] );
  writer->SetInput( resampler->GetOutput() );
  writer->Update();

  return EXIT_SUCCESS;
}

// entry point for the library; parameter 'args' is equivalent to 'argv' in (argc,argv) of commandline parameters to
// 'main()'
int ResampleImage( std::vector<std::string> args, std::ostream* /*out_stream = NULL */ )
{
  // put the arguments coming in as 'args' into standard (argc,argv) format;
  // 'args' doesn't have the command name as first, argument, so add it manually;
  // 'args' may have adjacent arguments concatenated into one argument,
  // which the parser should handle
  args.insert( args.begin(), "ResampleImage" );

  int     argc = args.size();
  char* * argv = new char *[args.size() + 1];
  for( unsigned int i = 0; i < args.size(); ++i )
    {
    // allocate space for the string plus a null character
    argv[i] = new char[args[i].length() + 1];
    std::strncpy( argv[i], args[i].c_str(), args[i].length() );
    // place the null character in the end
    argv[i][args[i].length()] = '\0';
    }
  argv[argc] = ITK_NULLPTR;
  // class to automatically cleanup argv upon destruction
  class Cleanup_argv
  {
public:
    Cleanup_argv( char* * argv_, int argc_plus_one_ ) : argv( argv_ ), argc_plus_one( argc_plus_one_ )
    {
    }

    ~Cleanup_argv()
    {
      for( unsigned int i = 0; i < argc_plus_one; ++i )
        {
        delete[] argv[i];
        }
      delete[] argv;
    }

private:
    char* *      argv;
    unsigned int argc_plus_one;
  };
  Cleanup_argv cleanup_argv( argv, argc + 1 );

  // antscout->set_stream( out_stream );

  if( argc < 5 )
    {
    std::cout << "Usage: " << argv[0] << " imageDimension inputImage "
             << "outputImage MxNxO [size=1,spacing=0] [interpolate type]" << std::endl;
    std::cout << "  Interpolation type: " << std::endl;
    std::cout << "    0. linear (default)" << std::endl;
    std::cout << "    1. nn " << std::endl;
    std::cout << "    2. gaussian [sigma=imageSpacing] [alpha=1.0]" << std::endl;
    std::cout << "    3. windowedSinc [type = 'c'osine, 'w'elch, 'b'lackman, 'l'anczos, 'h'amming]" << std::endl;
    std::cout << "    4. B-Spline [order=3]" << std::endl;
    if( argc >= 2 &&
        ( std::string( argv[1] ) == std::string("--help") || std::string( argv[1] ) == std::string("-h") ) )
      {
      return EXIT_SUCCESS;
      }
    return EXIT_FAILURE;
    }

  switch( atoi( argv[1] ) )
    {
    case 2:
      {
      ResampleImage<2>( argc, argv );
      }
      break;
    case 3:
      {
      ResampleImage<3>( argc, argv );
      }
      break;
    case 4:
      {
      ResampleImage<4>( argc, argv );
      }
      break;
    default:
      std::cout << "Unsupported dimension" << std::endl;
      return EXIT_FAILURE;
    }
  return EXIT_SUCCESS;
}
} // namespace ants
<commit_msg>ENH: ResampleImage.cxx for ANTsR<commit_after>
#include "antsUtilities.h"
#include <algorithm>

#include <stdio.h>

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

#include "itkResampleImageFilter.h"

#include "itkConstantBoundaryCondition.h"
#include "itkIdentityTransform.h"
#include "itkBSplineInterpolateImageFunction.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkGaussianInterpolateImageFunction.h"
#include "itkNearestNeighborInterpolateImageFunction.h"
#include "itkWindowedSincInterpolateImageFunction.h"
#include "ReadWriteData.h"
#include <string>
#include <vector>

namespace ants
{

template <unsigned int ImageDimension>
int ResampleImage( int argc, char *argv[] )
{
  typedef double                                RealType;
  typedef double                                PixelType;
  typedef itk::Image<PixelType, ImageDimension> ImageType;

  typename ImageType::Pointer image = ITK_NULLPTR;
  ReadImage<ImageType>( image, argv[2] );

  typedef itk::IdentityTransform<RealType, ImageDimension> TransformType;
  typename TransformType::Pointer transform = TransformType::New();
  transform->SetIdentity();

  typedef itk::LinearInterpolateImageFunction<ImageType, RealType>
    LinearInterpolatorType;
  typename LinearInterpolatorType::Pointer interpolator
    = LinearInterpolatorType::New();
  interpolator->SetInputImage( image );

  typedef itk::NearestNeighborInterpolateImageFunction<ImageType, RealType>
    NearestNeighborInterpolatorType;
  typename NearestNeighborInterpolatorType::Pointer nn_interpolator
    = NearestNeighborInterpolatorType::New();
  nn_interpolator->SetInputImage( image );

  typedef itk::BSplineInterpolateImageFunction<ImageType, RealType>
    BSplineInterpolatorType;
  typename BSplineInterpolatorType::Pointer bs_interpolator
    = BSplineInterpolatorType::New();
  bs_interpolator->SetInputImage( image );

  typedef itk::GaussianInterpolateImageFunction<ImageType, RealType>
    GaussianInterpolatorType;
  typename GaussianInterpolatorType::Pointer g_interpolator
    = GaussianInterpolatorType::New();
  g_interpolator->SetInputImage( image );

  typedef itk::WindowedSincInterpolateImageFunction<ImageType, 3> HammingInterpolatorType;
  typename HammingInterpolatorType::Pointer sh_interpolator = HammingInterpolatorType::New();
  sh_interpolator->SetInputImage( image );

  typedef itk::WindowedSincInterpolateImageFunction<ImageType, 3,
                                                    itk::Function::CosineWindowFunction<3> > Sinc1InterpolatorType;
  typename Sinc1InterpolatorType::Pointer sc_interpolator = Sinc1InterpolatorType::New();
  sc_interpolator->SetInputImage( image );

  typedef itk::WindowedSincInterpolateImageFunction<ImageType, 3,
                                                    itk::Function::WelchWindowFunction<3> > Sinc2InterpolatorType;
  typename Sinc2InterpolatorType::Pointer sw_interpolator = Sinc2InterpolatorType::New();
  sw_interpolator->SetInputImage( image );

  typedef itk::WindowedSincInterpolateImageFunction<ImageType, 3,
                                                    itk::Function::LanczosWindowFunction<3> > Sinc3InterpolatorType;
  typename Sinc3InterpolatorType::Pointer sl_interpolator = Sinc3InterpolatorType::New();
  sl_interpolator->SetInputImage( image );

  typename Sinc3InterpolatorType::Pointer sb_interpolator = Sinc3InterpolatorType::New();
  sb_interpolator->SetInputImage( image );

  typedef itk::ResampleImageFilter<ImageType, ImageType, RealType> ResamplerType;
  typename ResamplerType::Pointer resampler = ResamplerType::New();
  typename ResamplerType::SpacingType spacing;
  typename ResamplerType::SizeType size;

  std::vector<RealType> sp = ConvertVector<RealType>( std::string( argv[4] ) );

  if( argc <= 5 || atoi( argv[5] ) == 0 )
    {
    if( sp.size() == 1 )
      {
      spacing.Fill( sp[0] );
      }
    else if( sp.size() == ImageDimension )
      {
      for( unsigned int d = 0; d < ImageDimension; d++ )
        {
        spacing[d] = sp[d];
        }
      }
    else
      {
      std::cout << "Invalid spacing." << std::endl;
      }
    for( unsigned int i = 0; i < ImageDimension; i++ )
      {
      RealType spacing_old = image->GetSpacing()[i];
      RealType size_old = image->GetLargestPossibleRegion().GetSize()[i];
      size[i] = static_cast<int>( ( spacing_old * size_old ) / spacing[i] + 0.5 );
      }
    }
  else
    {
    if( sp.size() == 1 )
      {
      size.Fill( static_cast<unsigned int>( sp[0] ) );
      }
    else if( sp.size() == ImageDimension )
      {
      for( unsigned int d = 0; d < ImageDimension; d++ )
        {
        size[d] = static_cast<unsigned int>( sp[d] );
        }
      }
    else
      {
      std::cout << "Invalid size." << std::endl;
      }
    for( unsigned int i = 0; i < ImageDimension; i++ )
      {
      RealType spacing_old = image->GetSpacing()[i];
      RealType size_old = image->GetLargestPossibleRegion().GetSize()[i];
      spacing[i] = spacing_old * static_cast<float>( size_old - 1.0 )
        / static_cast<float>( size[i] - 1.0 );
      }
    }

  char arg7 = '\0';
  if( argc > 7 )
    {
    arg7 = *argv[7];
    }

  resampler->SetTransform( transform );
  resampler->SetInterpolator( interpolator );
  if( argc > 6 && atoi( argv[6] ) )
    {
    switch( atoi( argv[6] ) )
      {
      case 0: default:
        {
        resampler->SetInterpolator( interpolator );
        }
        break;
      case 1:
        {
        resampler->SetInterpolator( nn_interpolator );
        }
        break;
      case 2:
        {
        double sigma[ImageDimension];
        for( unsigned int d = 0; d < ImageDimension; d++ )
          {
          sigma[d] = image->GetSpacing()[d];
          }
        double alpha = 1.0;

        if( argc > 7 )
          {
          std::vector<RealType> sg = ConvertVector<RealType>( std::string( argv[7] ) );
          for( unsigned int d = 0; d < ImageDimension; d++ )
            {
            sigma[d] = sg[d];
            }
          }
        if( argc > 8 )
          {
          alpha = static_cast<double>( atof( argv[8] ) );
          }
        g_interpolator->SetParameters( sigma, alpha );

        resampler->SetInterpolator( g_interpolator );
        }
        break;
      case 3:
        {
        switch( arg7 )
          {
          case 'h': default:
            {
            resampler->SetInterpolator( sh_interpolator );
            }
            break;
          case 'c':
            {
            resampler->SetInterpolator( sc_interpolator );
            }
            break;
          case 'l':
            {
            resampler->SetInterpolator( sl_interpolator );
            }
            break;
          case 'w':
            {
            resampler->SetInterpolator( sw_interpolator );
            }
            break;
          case 'b':
            {
            resampler->SetInterpolator( sb_interpolator );
            }
            break;
          }
        }
      case 4:
        {
        if( argc > 7 && atoi( argv[7] ) >= 0 && atoi( argv[7] ) <= 5 )
          {
          bs_interpolator->SetSplineOrder( atoi( argv[7] ) );
          }
        else
          {
          bs_interpolator->SetSplineOrder( 3 );
          }
        resampler->SetInterpolator( bs_interpolator );
        }
        break;
      }
    }
  resampler->SetInput( image );
  resampler->SetSize( size );
  resampler->SetOutputOrigin( image->GetOrigin() );
  resampler->SetOutputDirection( image->GetDirection() );
  resampler->SetOutputSpacing( spacing );
  resampler->SetDefaultPixelValue( 0 );
  resampler->Update();

  WriteImage<ImageType>( resampler->GetOutput() , argv[3] );
  return EXIT_SUCCESS;
}

// entry point for the library; parameter 'args' is equivalent to 'argv' in (argc,argv) of commandline parameters to
// 'main()'
int ResampleImage( std::vector<std::string> args, std::ostream* /*out_stream = NULL */ )
{
  // put the arguments coming in as 'args' into standard (argc,argv) format;
  // 'args' doesn't have the command name as first, argument, so add it manually;
  // 'args' may have adjacent arguments concatenated into one argument,
  // which the parser should handle
  args.insert( args.begin(), "ResampleImage" );

  int     argc = args.size();
  char* * argv = new char *[args.size() + 1];
  for( unsigned int i = 0; i < args.size(); ++i )
    {
    // allocate space for the string plus a null character
    argv[i] = new char[args[i].length() + 1];
    std::strncpy( argv[i], args[i].c_str(), args[i].length() );
    // place the null character in the end
    argv[i][args[i].length()] = '\0';
    }
  argv[argc] = ITK_NULLPTR;
  // class to automatically cleanup argv upon destruction
  class Cleanup_argv
  {
public:
    Cleanup_argv( char* * argv_, int argc_plus_one_ ) : argv( argv_ ), argc_plus_one( argc_plus_one_ )
    {
    }

    ~Cleanup_argv()
    {
      for( unsigned int i = 0; i < argc_plus_one; ++i )
        {
        delete[] argv[i];
        }
      delete[] argv;
    }

private:
    char* *      argv;
    unsigned int argc_plus_one;
  };
  Cleanup_argv cleanup_argv( argv, argc + 1 );

  // antscout->set_stream( out_stream );

  if( argc < 5 )
    {
    std::cout << "Usage: " << argv[0] << " imageDimension inputImage "
             << "outputImage MxNxO [size=1,spacing=0] [interpolate type]" << std::endl;
    std::cout << "  Interpolation type: " << std::endl;
    std::cout << "    0. linear (default)" << std::endl;
    std::cout << "    1. nn " << std::endl;
    std::cout << "    2. gaussian [sigma=imageSpacing] [alpha=1.0]" << std::endl;
    std::cout << "    3. windowedSinc [type = 'c'osine, 'w'elch, 'b'lackman, 'l'anczos, 'h'amming]" << std::endl;
    std::cout << "    4. B-Spline [order=3]" << std::endl;
    if( argc >= 2 &&
        ( std::string( argv[1] ) == std::string("--help") || std::string( argv[1] ) == std::string("-h") ) )
      {
      return EXIT_SUCCESS;
      }
    return EXIT_FAILURE;
    }

  switch( atoi( argv[1] ) )
    {
    case 2:
      {
      ResampleImage<2>( argc, argv );
      }
      break;
    case 3:
      {
      ResampleImage<3>( argc, argv );
      }
      break;
    case 4:
      {
      ResampleImage<4>( argc, argv );
      }
      break;
    default:
      std::cout << "Unsupported dimension" << std::endl;
      return EXIT_FAILURE;
    }
  return EXIT_SUCCESS;
}
} // namespace ants
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------
//      $Id$
//    Version: $Name$
//
//    Copyright (C) 2005, 2006, 2008, 2009 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//---------------------------------------------------------------------------

#include <base/index_set.h>

#ifdef DEAL_II_USE_TRILINOS
#  ifdef DEAL_II_COMPILER_SUPPORTS_MPI
#    include <Epetra_MpiComm.h>
#  endif
#  include <Epetra_SerialComm.h>
#endif

DEAL_II_NAMESPACE_OPEN

void
IndexSet::compress () const
{
  if (is_compressed == true)
    return;
				   // see if any of the
				   // contiguous ranges can be
				   // merged. since they are sorted by
				   // their first index, determining
				   // overlap isn't all that hard
  for (std::vector<Range>::iterator
	 i = ranges.begin();
       i != ranges.end(); )
    {
      std::vector<Range>::iterator
	next = i;
      ++next;

      unsigned int first_index = i->begin;
      unsigned int last_index  = i->end;

				       // see if we can merge any of
				       // the following ranges
      bool can_merge = false;
      while (next != ranges.end() &&
	     (next->begin <= last_index))
	{
	  last_index = std::max (last_index, next->end);
	  ++next;
	  can_merge = true;
	}

      if (can_merge == true)
	{
					   // delete the old ranges
					   // and insert the new range
					   // in place of the previous
					   // one
	  *i = Range(first_index, last_index);
	  i = ranges.erase (i+1, next);
	}
      else
	++i;
    }

				   // now compute indices within set
  unsigned int next_index = 0;
  for (std::vector<Range>::iterator
	 i = ranges.begin();
       i != ranges.end();
       ++i)
    {
      i->nth_index_in_set = next_index;
      next_index += (i->end - i->begin);
    }
  is_compressed = true;

				   // check that next_index is
				   // correct. needs to be after the
				   // previous statement because we
				   // otherwise will get into an
				   // endless loop
  Assert (next_index == n_elements(), ExcInternalError());
}

#ifdef DEAL_II_USE_TRILINOS

Epetra_Map
IndexSet::make_trilinos_map (const MPI_Comm &communicator,
			     const bool overlapping) const
{
  compress ();

  if ((is_contiguous() == true) && (!overlapping))
    return Epetra_Map (size(),
		       n_elements(),
		       0,
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
		       Epetra_MpiComm(communicator));
#else
		       Epetra_SerialComm());
#endif
  else
    {
      std::vector<int> indices;
      indices.reserve(n_elements());
      for (std::vector<Range>::iterator
	     i = ranges.begin();
	   i != ranges.end();
	   ++i)
	for (unsigned int j=i->begin; j<i->end; ++j)
	  indices.push_back (j);
      Assert (indices.size() == n_elements(), ExcInternalError());

      return Epetra_Map (-1,
			 n_elements(),
			 &indices[0],
			 0,
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
			 Epetra_MpiComm(communicator));
#else
			 Epetra_SerialComm());
#endif
    }
}

#endif

DEAL_II_NAMESPACE_CLOSE
<commit_msg>Add missing include file.<commit_after>//---------------------------------------------------------------------------
//      $Id$
//    Version: $Name$
//
//    Copyright (C) 2005, 2006, 2008, 2009 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//---------------------------------------------------------------------------

#include <base/index_set.h>

#ifdef DEAL_II_USE_TRILINOS
#  ifdef DEAL_II_COMPILER_SUPPORTS_MPI
#    include <Epetra_MpiComm.h>
#  endif
#  include <Epetra_SerialComm.h>
#  include <Epetra_Map.h>
#endif

DEAL_II_NAMESPACE_OPEN

void
IndexSet::compress () const
{
  if (is_compressed == true)
    return;
				   // see if any of the
				   // contiguous ranges can be
				   // merged. since they are sorted by
				   // their first index, determining
				   // overlap isn't all that hard
  for (std::vector<Range>::iterator
	 i = ranges.begin();
       i != ranges.end(); )
    {
      std::vector<Range>::iterator
	next = i;
      ++next;

      unsigned int first_index = i->begin;
      unsigned int last_index  = i->end;

				       // see if we can merge any of
				       // the following ranges
      bool can_merge = false;
      while (next != ranges.end() &&
	     (next->begin <= last_index))
	{
	  last_index = std::max (last_index, next->end);
	  ++next;
	  can_merge = true;
	}

      if (can_merge == true)
	{
					   // delete the old ranges
					   // and insert the new range
					   // in place of the previous
					   // one
	  *i = Range(first_index, last_index);
	  i = ranges.erase (i+1, next);
	}
      else
	++i;
    }

				   // now compute indices within set
  unsigned int next_index = 0;
  for (std::vector<Range>::iterator
	 i = ranges.begin();
       i != ranges.end();
       ++i)
    {
      i->nth_index_in_set = next_index;
      next_index += (i->end - i->begin);
    }
  is_compressed = true;

				   // check that next_index is
				   // correct. needs to be after the
				   // previous statement because we
				   // otherwise will get into an
				   // endless loop
  Assert (next_index == n_elements(), ExcInternalError());
}

#ifdef DEAL_II_USE_TRILINOS

Epetra_Map
IndexSet::make_trilinos_map (const MPI_Comm &communicator,
			     const bool overlapping) const
{
  compress ();

  if ((is_contiguous() == true) && (!overlapping))
    return Epetra_Map (size(),
		       n_elements(),
		       0,
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
		       Epetra_MpiComm(communicator));
#else
		       Epetra_SerialComm());
#endif
  else
    {
      std::vector<int> indices;
      indices.reserve(n_elements());
      for (std::vector<Range>::iterator
	     i = ranges.begin();
	   i != ranges.end();
	   ++i)
	for (unsigned int j=i->begin; j<i->end; ++j)
	  indices.push_back (j);
      Assert (indices.size() == n_elements(), ExcInternalError());

      return Epetra_Map (-1,
			 n_elements(),
			 &indices[0],
			 0,
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
			 Epetra_MpiComm(communicator));
#else
			 Epetra_SerialComm());
#endif
    }
}

#endif

DEAL_II_NAMESPACE_CLOSE
<|endoftext|>


<commit_before>#include "WavTapDevice.hpp"
#include "WavTapEngine.hpp"
#include <IOKit/audio/IOAudioControl.h>
#include <IOKit/audio/IOAudioLevelControl.h>
#include <IOKit/audio/IOAudioToggleControl.h>
#include <IOKit/audio/IOAudioDefines.h>
#include <IOKit/IOLib.h>

#define super IOAudioDevice

OSDefineMetaClassAndStructors(WavTapDevice, IOAudioDevice)

const SInt32 WavTapDevice::kVolumeMax = 99;
const SInt32 WavTapDevice::kGainMax = 99;

bool WavTapDevice::initHardware(IOService *provider) {
  if (!super::initHardware(provider)) {
    return false;
  }
  setDeviceName("WavTap");
  setDeviceShortName("WavTap");
  setManufacturerName("WavTap");
  if (!createAudioEngines()){
    return false;
  }
  return true;
}

bool WavTapDevice::createAudioEngines() {
  OSArray *audioEngineArray = OSDynamicCast(OSArray, getProperty(AUDIO_ENGINES_KEY));
  OSCollectionIterator *audioEngineIterator;
  OSDictionary *audioEngineDict;
  if (!audioEngineArray) {
    IOLog("WavTapDevice[%p]::createAudioEngine() - Error: no AudioEngine array in personality.\n", this);
    return false;
  }
  audioEngineIterator = OSCollectionIterator::withCollection(audioEngineArray);
  if (!audioEngineIterator) {
    IOLog("WavTapDevice: no audio engines available.\n");
    return true;
  }
  while ((audioEngineDict = (OSDictionary*)audioEngineIterator->getNextObject())) {
    WavTapEngine *audioEngine = NULL;
    if (OSDynamicCast(OSDictionary, audioEngineDict) == NULL)
      continue;
    audioEngine = new WavTapEngine;
    if (!audioEngine)
      continue;
    if (!audioEngine->init(audioEngineDict))
      continue;
    initControls(audioEngine);
    activateAudioEngine(audioEngine);
    audioEngine->release();
  }
  audioEngineIterator->release();
  return true;
}

#define addControl(control, handler) \
  if (!control) {\
    IOLog("WavTap failed to add control.\n");  \
    return false; \
  } \
  control->setValueChangeHandler(handler, this); \
  audioEngine->addDefaultAudioControl(control); \
  control->release();

bool WavTapDevice::initControls(WavTapEngine* audioEngine) {
  IOAudioControl *control = NULL;
  for (UInt32 channel=0; channel <= NUM_CHANS; channel++) {
    mVolume[channel] = mGain[channel] = kVolumeMax;
    mMuteOut[channel] = mMuteIn[channel] = false;
  }
  const char *channelNameMap[NUM_CHANS+1] = {
    kIOAudioControlChannelNameAll,
    kIOAudioControlChannelNameLeft,
    kIOAudioControlChannelNameRight,
    kIOAudioControlChannelNameCenter,
    kIOAudioControlChannelNameLeftRear,
    kIOAudioControlChannelNameRightRear,
    kIOAudioControlChannelNameSub
  };
  for (UInt32 channel=7; channel <= NUM_CHANS; channel++)
    channelNameMap[channel] = "Unknown Channel";
  for (unsigned channel=0; channel <= NUM_CHANS; channel++) {
    control = IOAudioLevelControl::createVolumeControl(WavTapDevice::kVolumeMax, 0, WavTapDevice::kVolumeMax, (-40 << 16) + (32768), 0, channel, channelNameMap[channel], channel, kIOAudioControlUsageOutput);
    addControl(control, (IOAudioControl::IntValueChangeHandler)volumeChangeHandler);
    control = IOAudioLevelControl::createVolumeControl(WavTapDevice::kGainMax, 0, WavTapDevice::kGainMax, 0, (40 << 16) + (32768), channel, channelNameMap[channel], channel, kIOAudioControlUsageInput);
    addControl(control, (IOAudioControl::IntValueChangeHandler)gainChangeHandler);
  }
  control = IOAudioToggleControl::createMuteControl(false, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsageOutput);
  addControl(control, (IOAudioControl::IntValueChangeHandler)outputMuteChangeHandler);
  control = IOAudioToggleControl::createMuteControl(false, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsageInput);
  addControl(control, (IOAudioControl::IntValueChangeHandler)inputMuteChangeHandler);
  return true;
}

IOReturn WavTapDevice::volumeChangeHandler(IOService *target, IOAudioControl *volumeControl, SInt32 oldValue, SInt32 newValue) {
  IOReturn result = kIOReturnBadArgument;
  WavTapDevice *audioDevice = (WavTapDevice *)target;
  if (audioDevice)
    result = audioDevice->volumeChanged(volumeControl, oldValue, newValue);
  return result;
}

IOReturn WavTapDevice::volumeChanged(IOAudioControl *volumeControl, SInt32 oldValue, SInt32 newValue) {
  if (volumeControl)
    mVolume[volumeControl->getChannelID()] = newValue;
  return kIOReturnSuccess;
}

IOReturn WavTapDevice::outputMuteChangeHandler(IOService *target, IOAudioControl *muteControl, SInt32 oldValue, SInt32 newValue) {
  IOReturn result = kIOReturnBadArgument;
  WavTapDevice *audioDevice = (WavTapDevice*)target;
  if (audioDevice)
    result = audioDevice->outputMuteChanged(muteControl, oldValue, newValue);
  return result;
}

IOReturn WavTapDevice::outputMuteChanged(IOAudioControl *muteControl, SInt32 oldValue, SInt32 newValue) {
  if (muteControl)
    mMuteOut[muteControl->getChannelID()] = newValue;
  return kIOReturnSuccess;
}

IOReturn WavTapDevice::gainChangeHandler(IOService *target, IOAudioControl *gainControl, SInt32 oldValue, SInt32 newValue) {
  IOReturn result = kIOReturnBadArgument;
  WavTapDevice *audioDevice = (WavTapDevice *)target;
  if (audioDevice)
    result = audioDevice->gainChanged(gainControl, oldValue, newValue);
  return result;
}

IOReturn WavTapDevice::gainChanged(IOAudioControl *gainControl, SInt32 oldValue, SInt32 newValue) {
  if (gainControl)
    mGain[gainControl->getChannelID()] = newValue;
  return kIOReturnSuccess;
}

IOReturn WavTapDevice::inputMuteChangeHandler(IOService *target, IOAudioControl *muteControl, SInt32 oldValue, SInt32 newValue) {
  IOReturn result = kIOReturnBadArgument;
  WavTapDevice *audioDevice = (WavTapDevice*)target;
  if (audioDevice)
    result = audioDevice->inputMuteChanged(muteControl, oldValue, newValue);
  return result;
}

IOReturn WavTapDevice::inputMuteChanged(IOAudioControl *muteControl, SInt32 oldValue, SInt32 newValue) {
  if (muteControl)
    mMuteIn[muteControl->getChannelID()] = newValue;
  return kIOReturnSuccess;
}
<commit_msg>[formatting] I just like when assignments have their own line<commit_after>#include "WavTapDevice.hpp"
#include "WavTapEngine.hpp"
#include <IOKit/audio/IOAudioControl.h>
#include <IOKit/audio/IOAudioLevelControl.h>
#include <IOKit/audio/IOAudioToggleControl.h>
#include <IOKit/audio/IOAudioDefines.h>
#include <IOKit/IOLib.h>

#define super IOAudioDevice

OSDefineMetaClassAndStructors(WavTapDevice, IOAudioDevice)

const SInt32 WavTapDevice::kVolumeMax = 99;
const SInt32 WavTapDevice::kGainMax = 99;

bool WavTapDevice::initHardware(IOService *provider) {
  if (!super::initHardware(provider)) {
    return false;
  }
  setDeviceName("WavTap");
  setDeviceShortName("WavTap");
  setManufacturerName("WavTap");
  if (!createAudioEngines()){
    return false;
  }
  return true;
}

bool WavTapDevice::createAudioEngines() {
  OSArray *audioEngineArray = OSDynamicCast(OSArray, getProperty(AUDIO_ENGINES_KEY));
  OSCollectionIterator *audioEngineIterator;
  OSDictionary *audioEngineDict;
  if (!audioEngineArray) {
    IOLog("WavTapDevice[%p]::createAudioEngine() - Error: no AudioEngine array in personality.\n", this);
    return false;
  }
  audioEngineIterator = OSCollectionIterator::withCollection(audioEngineArray);
  if (!audioEngineIterator) {
    IOLog("WavTapDevice: no audio engines available.\n");
    return true;
  }
  while ((audioEngineDict = (OSDictionary*)audioEngineIterator->getNextObject())) {
    WavTapEngine *audioEngine = NULL;
    if (OSDynamicCast(OSDictionary, audioEngineDict) == NULL)
      continue;
    audioEngine = new WavTapEngine;
    if (!audioEngine)
      continue;
    if (!audioEngine->init(audioEngineDict))
      continue;
    initControls(audioEngine);
    activateAudioEngine(audioEngine);
    audioEngine->release();
  }
  audioEngineIterator->release();
  return true;
}

#define addControl(control, handler) \
  if (!control) {\
    IOLog("WavTap failed to add control.\n");  \
    return false; \
  } \
  control->setValueChangeHandler(handler, this); \
  audioEngine->addDefaultAudioControl(control); \
  control->release();

bool WavTapDevice::initControls(WavTapEngine* audioEngine) {
  IOAudioControl *control = NULL;
  for (UInt32 channel = 0; channel <= NUM_CHANS; channel++) {
    mGain[channel] = kVolumeMax;
    mVolume[channel] = kVolumeMax;
    mMuteIn[channel] = false;
    mMuteOut[channel] = false;
  }
  const char *channelNameMap[NUM_CHANS+1] = {
    kIOAudioControlChannelNameAll,
    kIOAudioControlChannelNameLeft,
    kIOAudioControlChannelNameRight,
    kIOAudioControlChannelNameCenter,
    kIOAudioControlChannelNameLeftRear,
    kIOAudioControlChannelNameRightRear,
    kIOAudioControlChannelNameSub
  };
  for (UInt32 channel=7; channel <= NUM_CHANS; channel++)
    channelNameMap[channel] = "Unknown Channel";
  for (unsigned channel=0; channel <= NUM_CHANS; channel++) {
    control = IOAudioLevelControl::createVolumeControl(WavTapDevice::kVolumeMax, 0, WavTapDevice::kVolumeMax, (-40 << 16) + (32768), 0, channel, channelNameMap[channel], channel, kIOAudioControlUsageOutput);
    addControl(control, (IOAudioControl::IntValueChangeHandler)volumeChangeHandler);
    control = IOAudioLevelControl::createVolumeControl(WavTapDevice::kGainMax, 0, WavTapDevice::kGainMax, 0, (40 << 16) + (32768), channel, channelNameMap[channel], channel, kIOAudioControlUsageInput);
    addControl(control, (IOAudioControl::IntValueChangeHandler)gainChangeHandler);
  }
  control = IOAudioToggleControl::createMuteControl(false, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsageOutput);
  addControl(control, (IOAudioControl::IntValueChangeHandler)outputMuteChangeHandler);
  control = IOAudioToggleControl::createMuteControl(false, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsageInput);
  addControl(control, (IOAudioControl::IntValueChangeHandler)inputMuteChangeHandler);
  return true;
}

IOReturn WavTapDevice::volumeChangeHandler(IOService *target, IOAudioControl *volumeControl, SInt32 oldValue, SInt32 newValue) {
  IOReturn result = kIOReturnBadArgument;
  WavTapDevice *audioDevice = (WavTapDevice *)target;
  if (audioDevice)
    result = audioDevice->volumeChanged(volumeControl, oldValue, newValue);
  return result;
}

IOReturn WavTapDevice::volumeChanged(IOAudioControl *volumeControl, SInt32 oldValue, SInt32 newValue) {
  if (volumeControl)
    mVolume[volumeControl->getChannelID()] = newValue;
  return kIOReturnSuccess;
}

IOReturn WavTapDevice::outputMuteChangeHandler(IOService *target, IOAudioControl *muteControl, SInt32 oldValue, SInt32 newValue) {
  IOReturn result = kIOReturnBadArgument;
  WavTapDevice *audioDevice = (WavTapDevice*)target;
  if (audioDevice)
    result = audioDevice->outputMuteChanged(muteControl, oldValue, newValue);
  return result;
}

IOReturn WavTapDevice::outputMuteChanged(IOAudioControl *muteControl, SInt32 oldValue, SInt32 newValue) {
  if (muteControl)
    mMuteOut[muteControl->getChannelID()] = newValue;
  return kIOReturnSuccess;
}

IOReturn WavTapDevice::gainChangeHandler(IOService *target, IOAudioControl *gainControl, SInt32 oldValue, SInt32 newValue) {
  IOReturn result = kIOReturnBadArgument;
  WavTapDevice *audioDevice = (WavTapDevice *)target;
  if (audioDevice)
    result = audioDevice->gainChanged(gainControl, oldValue, newValue);
  return result;
}

IOReturn WavTapDevice::gainChanged(IOAudioControl *gainControl, SInt32 oldValue, SInt32 newValue) {
  if (gainControl)
    mGain[gainControl->getChannelID()] = newValue;
  return kIOReturnSuccess;
}

IOReturn WavTapDevice::inputMuteChangeHandler(IOService *target, IOAudioControl *muteControl, SInt32 oldValue, SInt32 newValue) {
  IOReturn result = kIOReturnBadArgument;
  WavTapDevice *audioDevice = (WavTapDevice*)target;
  if (audioDevice)
    result = audioDevice->inputMuteChanged(muteControl, oldValue, newValue);
  return result;
}

IOReturn WavTapDevice::inputMuteChanged(IOAudioControl *muteControl, SInt32 oldValue, SInt32 newValue) {
  if (muteControl)
    mMuteIn[muteControl->getChannelID()] = newValue;
  return kIOReturnSuccess;
}
<|endoftext|>