<commit_before>/*
* Copyright 2006-2008 The FLWOR Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "validate.h"
#ifndef ZORBA_NO_XMLSCHEMA

#include "system/globalenv.h"

#include "types/casting.h"
#include "types/typeops.h"
#include "types/schema/SchemaValidatorFilter.h"
#include "types/schema/StrX.h"

#include "runtime/validate/validate.h"
#include "runtime/api/runtimecb.h"
#include "runtime/accessors/AccessorsImpl.h"
#include "runtime/api/plan_iterator_wrapper.h"
#include "runtime/util/item_iterator.h"

#include "store/api/item.h"
#include "store/api/item_factory.h"
#include "store/api/copymode.h"
#include "store/api/store.h"
#include "store/api/temp_seq.h"

#include "context/dynamic_context.h"
#include "context/static_context.h"
#include "context/collation_cache.h"
#include "context/namespace_context.h"
#include "zorbatypes/duration.h"
#include "zorbatypes/datetime.h"
#include "zorbaerrors/error_messages.h"
#include "zorbaerrors/errors.h"

namespace zorba
{

    /*______________________________________________________________________
    |
    | 3.13
    | validate [ | lax | strict] {  }
    |
    | A validate expression returns a new node with its own identity and
    | with no parent. The new node and its descendants are given type
    | annotations that are generated by applying a validation process to
    | the operand node. In some cases, default values may also be generated
    | by the validation process.
    |_______________________________________________________________________*/
    ValidateIterator::ValidateIterator ( const QueryLoc& loc, PlanIter_t& aIter, bool isLax )
        :
    UnaryBaseIterator<ValidateIterator, PlanIteratorState> ( loc, aIter ) , _isLax(isLax)
    {}

    ValidateIterator::~ValidateIterator()
    {}

    bool ValidateIterator::nextImpl(store::Item_t& result, PlanState& planState) const
    {
        PlanIteratorState* aState;
        DEFAULT_STACK_INIT(PlanIteratorState, aState, planState);
        STACK_PUSH (
            ValidateIterator::effectiveValidationValue ( result, this->loc, planState, theChild, _isLax ),
            aState
            );
        STACK_END (aState);
    }

    bool ValidateIterator::effectiveValidationValue ( store::Item_t& result, const QueryLoc& loc,
        PlanState& planState, const PlanIterator* iter, bool isLax)
    {
        //std::cout << "Starting Validation" << "\n"; std::cout.flush();

        bool returnVal = false;
        store::Item_t item;
        xqtref_t type;

        bool valid = consumeNext(item, iter, planState);

        if ( !valid )
        {
             ZORBA_ERROR_LOC_DESC( XQDY0061, loc, "Wrong arguments in validate expression.");
        }
        else if ( item->isNode() )
        {
            static_context* staticContext = planState.sctx();

            TypeManager * typeManager = staticContext->get_typemanager();
            DelegatingTypeManager* delegatingTypeManager =
                static_cast<DelegatingTypeManager*>(typeManager);

            Schema* schema = delegatingTypeManager->getSchema();
            if ( !schema )
            {
                // no schema available - items remain the same
                result = item;
                return true;
            }

#ifndef ZORBA_NO_XMLSCHEMA
            xqpStringStore_t baseUri = planState.theRuntimeCB->theStaticContext->
                final_baseuri().getStore();

            SchemaValidator schemaValidator = SchemaValidator(typeManager,
                schema->getGrammarPool(), isLax, loc);

            switch ( item->getNodeKind() )
            {
            case store::StoreConsts::documentNode:
            {
                //std::cout << "Validate document" << "\n"; std::cout.flush();

                schemaValidator.startDoc();

                xqpStringStore_t docBaseUri = item->getBaseURI();
                xqpStringStore_t docUri = item->getDocumentURI();
                store::Item_t newDoc;
                GENV_ITEMFACTORY->createDocumentNode(newDoc, docBaseUri, docUri, true);

                processChildren( planState, delegatingTypeManager, schemaValidator, newDoc, item->getChildren() );

                schemaValidator.endDoc();

                //std::cout << "End Validate doc" << "\n"; std::cout.flush();

                result = newDoc;
                return true;
            }
            case store::StoreConsts::elementNode:
            {
                //std::cout << "Validate element" << "\n"; std::cout.flush();

                schemaValidator.startDoc();

                store::Item_t newElem = processElement(planState, delegatingTypeManager, schemaValidator, NULL, item);

                schemaValidator.endDoc();

                //std::cout << "End Validate elem" << "\n"; std::cout.flush();

                result = newElem;
                return true;
            }
            default:
                ZORBA_ERROR_LOC_DESC( XQDY0061, loc,
                    "Argument in validate expression not a document or element node.");
                returnVal = false;
                result = NULL;
            }
#endif // ZORBA_NO_XMLSCHEMA
        }
        else
        {
            ZORBA_ERROR_LOC_DESC( XQDY0061, loc, "Argument in validate expression not a document node.");
            returnVal = false;
            result = NULL;
        }

        return returnVal;
    }

#ifndef ZORBA_NO_XMLSCHEMA
    store::Item_t ValidateIterator::processElement( PlanState& planState, DelegatingTypeManager* delegatingTypeManager,
        SchemaValidator& schemaValidator, store::Item *parent, const store::Item_t& element)
    {
        ZORBA_ASSERT(element->isNode());
        ZORBA_ASSERT(element->getNodeKind() == store::StoreConsts::elementNode);

        store::Item_t nodeName = element->getNodeName();
        xqpStringStore_t baseUri = element->getBaseURI();

        schemaValidator.startElem(nodeName);

        // namespace declarations must go first
        processNamespaces( schemaValidator, element);

        // since the type of an element is determined only after the validator receives all
        // of it's attributes, and an attribute node needs it's parent when created
        // we need to go through the attributes twice: once for validation and once for creation
        validateAttributes(schemaValidator, element->getAttributes());

        store::Item_t typeName = schemaValidator.getTypeQName();

        store::Item_t newElem;

        store::NsBindings bindings;
        element->getNamespaceBindings(bindings);

        store::Item_t elemName = element->getNodeName();
        GENV_ITEMFACTORY->createElementNode(newElem, parent, -1, elemName,
                                            typeName, true, false, false, false,
                                            bindings, baseUri, false);

        processAttributes( planState, delegatingTypeManager, schemaValidator, (store::Item *)newElem,
            element->getAttributes());

        processChildren( planState, delegatingTypeManager, schemaValidator, (store::Item *)newElem,
            element->getChildren());

        schemaValidator.endElem(nodeName);

        return newElem;
    }

    void ValidateIterator::validateAttributes( SchemaValidator& schemaValidator, store::Iterator_t attributes)
    {
        store::Item_t attribute;

        while ( attributes->next(attribute) )
        {
            ZORBA_ASSERT(attribute->isNode());
            ZORBA_ASSERT(attribute->getNodeKind() == store::StoreConsts::attributeNode);

            std::cout << " v    - attr: " << attribute->getNodeName()->getLocalName()->c_str() << "\n"; std::cout.flush();

            store::Item_t attName = attribute->getNodeName();
            schemaValidator.attr(attName, attribute->getStringValue());
        }
    }

    void ValidateIterator::processAttributes( PlanState& planState, DelegatingTypeManager* delegatingTypeManager,
        SchemaValidator& schemaValidator, store::Item *parent, store::Iterator_t attributes)
    {
        std::list<AttributeValidationInfo*>* attList = schemaValidator.getAttributeList();
        std::list<AttributeValidationInfo*>::iterator curAtt;

        for( curAtt = attList->begin() ; curAtt != attList->end(); ++curAtt )
        {
            AttributeValidationInfo* att = *curAtt;
            std::cout << " v    proccessATT2: " << att->_localName << " T: " << att->_typeName << "\n";

            store::Item_t attQName;
            GENV_ITEMFACTORY->createQName( attQName, att->_uri, att->_prefix, att->_localName);

            std::string typePrefix;
            if ( std::strcmp(Schema::XSD_NAMESPACE, att->_typeURI->c_str() )==0 ) // hack around typeManager bug for comparing QNames
                typePrefix = "xs";
            else
                typePrefix = "";

            store::Item_t typeQName;
            GENV_ITEMFACTORY->createQName(typeQName, att->_typeURI, new xqpStringStore(typePrefix), att->_typeName);

            store::NsBindings bindings;
            parent->getNamespaceBindings(bindings);
            std::vector<store::Item_t> typedValues;
            processTextValue(planState, delegatingTypeManager, bindings, typeQName, att->_value, typedValues);

            store::Item_t validatedAttNode;
            if ( typedValues.size()==1 ) // hack around serialization bug
                GENV_ITEMFACTORY->createAttributeNode( validatedAttNode, parent, -1, attQName,
                    typeQName, typedValues[0], false, false );
            else
                GENV_ITEMFACTORY->createAttributeNode( validatedAttNode, parent, -1, attQName,
                    typeQName, typedValues, false, false );
        }
    }

    void ValidateIterator::processChildren( PlanState& planState, DelegatingTypeManager* delegatingTypeManager,
        SchemaValidator& schemaValidator, store::Item *parent, store::Iterator_t children)
    {
        store::Item_t child;

        store::Item_t typeName;

        while ( children->next(child) )
        {
            if ( child->isNode() )
            {
                //std::cout << "  > child: " << child->getNodeKind() << " " << child->getType()->getLocalName()->c_str() << "\n";
                //std::cout.flush();

                switch ( child->getNodeKind() )
                {
                case store::StoreConsts::elementNode:
                    processElement( planState, delegatingTypeManager, schemaValidator, parent, child);
                    break;

                case store::StoreConsts::attributeNode:
                    ZORBA_ASSERT(false);
                    break;

                case store::StoreConsts::documentNode:
                    ZORBA_ASSERT(false);
                    break;

                case store::StoreConsts::textNode:
                    {
                        //std::cout << "     - text: " << child->getStringValue() << "\n"; std::cout.flush();
                        xqpStringStore_t childStringValue = child->getStringValue();
                        schemaValidator.text(childStringValue);

                        store::Item_t type = schemaValidator.getTypeQName();

                        store::NsBindings nsBindings;
                        parent->getNamespaceBindings(nsBindings);
                        std::vector<store::Item_t> typedValues;
                        processTextValue(planState, delegatingTypeManager, nsBindings, type, childStringValue, typedValues );

                        store::Item_t validatedTextNode;
                        if ( typedValues.size()==1 ) // hack around serialization bug
                            GENV_ITEMFACTORY->createTextNode(validatedTextNode, parent, typedValues[0]);
                        else
                            GENV_ITEMFACTORY->createTextNode(validatedTextNode, parent, typedValues);
                    }
                    break;

                case store::StoreConsts::piNode:
                    {
                        //std::cout << "     - pi: " << child->getStringValue() << "\n"; std::cout.flush();
                        store::Item_t piNode;
                        xqpStringStore_t piTarget = child->getTarget();
                        xqpStringStore_t childStringValue = child->getStringValue();
                        xqpStringStore_t childBaseUri = child->getBaseURI();
                        GENV_ITEMFACTORY->createPiNode(piNode, parent, -1, piTarget, childStringValue, childBaseUri);
                    }
                    break;

                case store::StoreConsts::commentNode:
                    {
                        //std::cout << "     - comment: " << child->getStringValue() << "\n"; std::cout.flush();
                        store::Item_t commentNode;
                        xqpStringStore_t childStringValue = child->getStringValue();
                        GENV_ITEMFACTORY->createCommentNode(commentNode, parent, -1, childStringValue);
                    }
                    break;

                case store::StoreConsts::anyNode:
                    //std::cout << "     - any: " << child->getStringValue() << "\n"; std::cout.flush();
                    ZORBA_ASSERT(false);
                    break;

                default:
                    ZORBA_ASSERT(false);
                }
            }
        }
    }

    void ValidateIterator::processNamespaces ( SchemaValidator& schemaValidator, const store::Item_t& item)
    {
        store::NsBindings bindings;
        item->getNamespaceBindings(bindings, store::StoreConsts::ONLY_LOCAL_NAMESPACES);

        for (unsigned long i = 0; i < bindings.size(); i++)
        {
            schemaValidator.ns( bindings[i].first.getStore(), bindings[i].second.getStore() );
        }
    }

    void ValidateIterator::processTextValue (PlanState& planState, DelegatingTypeManager* delegatingTypeManager,
        store::NsBindings& bindings, store::Item_t typeQName, xqpStringStore_t& textValue,
        std::vector<store::Item_t> &resultList)
    {
        xqtref_t type = delegatingTypeManager->create_named_atomic_type(typeQName, TypeConstants::QUANT_ONE);
        //std::cout << "     - processTextValue: " << typeQName->getPrefix()->str() << ":" << typeQName->getLocalName()->str() << "@" <<
        //    typeQName->getNamespace()->str() ; std::cout.flush();
        //std::cout << " type: " << ( type==NULL ? "NULL" : type->toString()) << "\n"; std::cout.flush();

        static_context* staticContext = planState.sctx();
        namespace_context nsCtx = namespace_context(staticContext, bindings);

        store::Item_t result;
        if (type!=NULL)
        {
            bool listOrUnion = false;
            if ( type->type_kind() == XQType::USER_DEFINED_KIND )
            {
                const UserDefinedXQType udXQType = static_cast<const UserDefinedXQType&>(*type);
                if ( udXQType.isList() || udXQType.isUnion() )
                {
                    listOrUnion = true;
                }
            }

            if ( listOrUnion )
            {
                xqp_string str(textValue);
                delegatingTypeManager->getSchema()->
                    parseUserSimpleTypes(str, type, resultList);
            }
            else
            {
                bool isResult = GenericCast::instance()->castToAtomic(result, textValue, type.getp(), &nsCtx);
                if ( isResult )
                    resultList.push_back(result);
            }
        }
        else
        {
            if ( GENV_ITEMFACTORY->createUntypedAtomic( result, textValue) )
                resultList.push_back(result);
        }
    }

#endif//#ifndef ZORBA_NO_XMLSCHEMA

    /* end class ValidateIterator */
}

#endif // ifndef ZORBA_NO_XMLSCHEMA
<commit_msg>Call diffrent API for creating text when type has mixed content.<commit_after>/*
* Copyright 2006-2008 The FLWOR Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "validate.h"
#ifndef ZORBA_NO_XMLSCHEMA

#include "system/globalenv.h"

#include "types/casting.h"
#include "types/typeops.h"
#include "types/schema/SchemaValidatorFilter.h"
#include "types/schema/StrX.h"

#include "runtime/validate/validate.h"
#include "runtime/api/runtimecb.h"
#include "runtime/accessors/AccessorsImpl.h"
#include "runtime/api/plan_iterator_wrapper.h"
#include "runtime/util/item_iterator.h"

#include "store/api/item.h"
#include "store/api/item_factory.h"
#include "store/api/copymode.h"
#include "store/api/store.h"
#include "store/api/temp_seq.h"

#include "context/dynamic_context.h"
#include "context/static_context.h"
#include "context/collation_cache.h"
#include "context/namespace_context.h"
#include "zorbatypes/duration.h"
#include "zorbatypes/datetime.h"
#include "zorbaerrors/error_messages.h"
#include "zorbaerrors/errors.h"

namespace zorba
{

    /*______________________________________________________________________
    |
    | 3.13
    | validate [ | lax | strict] {  }
    |
    | A validate expression returns a new node with its own identity and
    | with no parent. The new node and its descendants are given type
    | annotations that are generated by applying a validation process to
    | the operand node. In some cases, default values may also be generated
    | by the validation process.
    |_______________________________________________________________________*/
    ValidateIterator::ValidateIterator ( const QueryLoc& loc, PlanIter_t& aIter, bool isLax )
        :
    UnaryBaseIterator<ValidateIterator, PlanIteratorState> ( loc, aIter ) , _isLax(isLax)
    {}

    ValidateIterator::~ValidateIterator()
    {}

    bool ValidateIterator::nextImpl(store::Item_t& result, PlanState& planState) const
    {
        PlanIteratorState* aState;
        DEFAULT_STACK_INIT(PlanIteratorState, aState, planState);
        STACK_PUSH (
            ValidateIterator::effectiveValidationValue ( result, this->loc, planState, theChild, _isLax ),
            aState
            );
        STACK_END (aState);
    }

    bool ValidateIterator::effectiveValidationValue ( store::Item_t& result, const QueryLoc& loc,
        PlanState& planState, const PlanIterator* iter, bool isLax)
    {
        //std::cout << "Starting Validation" << "\n"; std::cout.flush();

        bool returnVal = false;
        store::Item_t item;
        xqtref_t type;

        bool valid = consumeNext(item, iter, planState);

        if ( !valid )
        {
             ZORBA_ERROR_LOC_DESC( XQDY0061, loc, "Wrong arguments in validate expression.");
        }
        else if ( item->isNode() )
        {
            static_context* staticContext = planState.sctx();

            TypeManager * typeManager = staticContext->get_typemanager();
            DelegatingTypeManager* delegatingTypeManager =
                static_cast<DelegatingTypeManager*>(typeManager);

            Schema* schema = delegatingTypeManager->getSchema();
            if ( !schema )
            {
                // no schema available - items remain the same
                result = item;
                return true;
            }

#ifndef ZORBA_NO_XMLSCHEMA
            xqpStringStore_t baseUri = planState.theRuntimeCB->theStaticContext->
                final_baseuri().getStore();

            SchemaValidator schemaValidator = SchemaValidator(typeManager,
                schema->getGrammarPool(), isLax, loc);

            switch ( item->getNodeKind() )
            {
            case store::StoreConsts::documentNode:
            {
                //std::cout << "Validate document" << "\n"; std::cout.flush();

                schemaValidator.startDoc();

                xqpStringStore_t docBaseUri = item->getBaseURI();
                xqpStringStore_t docUri = item->getDocumentURI();
                store::Item_t newDoc;
                GENV_ITEMFACTORY->createDocumentNode(newDoc, docBaseUri, docUri, true);

                processChildren( planState, delegatingTypeManager, schemaValidator, newDoc, item->getChildren() );

                schemaValidator.endDoc();

                //std::cout << "End Validate doc" << "\n"; std::cout.flush();

                result = newDoc;
                return true;
            }
            case store::StoreConsts::elementNode:
            {
                //std::cout << "Validate element" << "\n"; std::cout.flush();

                schemaValidator.startDoc();

                store::Item_t newElem = processElement(planState, delegatingTypeManager, schemaValidator, NULL, item);

                schemaValidator.endDoc();

                //std::cout << "End Validate elem" << "\n"; std::cout.flush();

                result = newElem;
                return true;
            }
            default:
                ZORBA_ERROR_LOC_DESC( XQDY0061, loc,
                    "Argument in validate expression not a document or element node.");
                returnVal = false;
                result = NULL;
            }
#endif // ZORBA_NO_XMLSCHEMA
        }
        else
        {
            ZORBA_ERROR_LOC_DESC( XQDY0061, loc, "Argument in validate expression not a document node.");
            returnVal = false;
            result = NULL;
        }

        return returnVal;
    }

#ifndef ZORBA_NO_XMLSCHEMA
    store::Item_t ValidateIterator::processElement( PlanState& planState, DelegatingTypeManager* delegatingTypeManager,
        SchemaValidator& schemaValidator, store::Item *parent, const store::Item_t& element)
    {
        ZORBA_ASSERT(element->isNode());
        ZORBA_ASSERT(element->getNodeKind() == store::StoreConsts::elementNode);

        store::Item_t nodeName = element->getNodeName();
        xqpStringStore_t baseUri = element->getBaseURI();

        schemaValidator.startElem(nodeName);

        // namespace declarations must go first
        processNamespaces( schemaValidator, element);

        // since the type of an element is determined only after the validator receives all
        // of it's attributes, and an attribute node needs it's parent when created
        // we need to go through the attributes twice: once for validation and once for creation
        validateAttributes(schemaValidator, element->getAttributes());

        store::Item_t typeName = schemaValidator.getTypeQName();

        store::Item_t newElem;

        store::NsBindings bindings;
        element->getNamespaceBindings(bindings);

        store::Item_t elemName = element->getNodeName();
        GENV_ITEMFACTORY->createElementNode(newElem, parent, -1, elemName,
                                            typeName, true, false, false, false,
                                            bindings, baseUri, false);

        processAttributes( planState, delegatingTypeManager, schemaValidator, (store::Item *)newElem,
            element->getAttributes());

        processChildren( planState, delegatingTypeManager, schemaValidator, (store::Item *)newElem,
            element->getChildren());

        schemaValidator.endElem(nodeName);

        return newElem;
    }

    void ValidateIterator::validateAttributes( SchemaValidator& schemaValidator, store::Iterator_t attributes)
    {
        store::Item_t attribute;

        while ( attributes->next(attribute) )
        {
            ZORBA_ASSERT(attribute->isNode());
            ZORBA_ASSERT(attribute->getNodeKind() == store::StoreConsts::attributeNode);

            std::cout << " v    - attr: " << attribute->getNodeName()->getLocalName()->c_str() << "\n"; std::cout.flush();

            store::Item_t attName = attribute->getNodeName();
            schemaValidator.attr(attName, attribute->getStringValue());
        }
    }

    void ValidateIterator::processAttributes( PlanState& planState, DelegatingTypeManager* delegatingTypeManager,
        SchemaValidator& schemaValidator, store::Item *parent, store::Iterator_t attributes)
    {
        std::list<AttributeValidationInfo*>* attList = schemaValidator.getAttributeList();
        std::list<AttributeValidationInfo*>::iterator curAtt;

        for( curAtt = attList->begin() ; curAtt != attList->end(); ++curAtt )
        {
            AttributeValidationInfo* att = *curAtt;
            std::cout << " v    proccessATT2: " << att->_localName << " T: " << att->_typeName << "\n";

            store::Item_t attQName;
            GENV_ITEMFACTORY->createQName( attQName, att->_uri, att->_prefix, att->_localName);

            std::string typePrefix;
            if ( std::strcmp(Schema::XSD_NAMESPACE, att->_typeURI->c_str() )==0 ) // hack around typeManager bug for comparing QNames
                typePrefix = "xs";
            else
                typePrefix = "";

            store::Item_t typeQName;
            GENV_ITEMFACTORY->createQName(typeQName, att->_typeURI, new xqpStringStore(typePrefix), att->_typeName);

            store::NsBindings bindings;
            parent->getNamespaceBindings(bindings);
            std::vector<store::Item_t> typedValues;
            processTextValue(planState, delegatingTypeManager, bindings, typeQName, att->_value, typedValues);

            store::Item_t validatedAttNode;
            if ( typedValues.size()==1 ) // hack around serialization bug
                GENV_ITEMFACTORY->createAttributeNode( validatedAttNode, parent, -1, attQName,
                    typeQName, typedValues[0], false, false );
            else
                GENV_ITEMFACTORY->createAttributeNode( validatedAttNode, parent, -1, attQName,
                    typeQName, typedValues, false, false );
        }
    }

    void ValidateIterator::processChildren( PlanState& planState, DelegatingTypeManager* delegatingTypeManager,
        SchemaValidator& schemaValidator, store::Item *parent, store::Iterator_t children)
    {
        store::Item_t child;

        store::Item_t typeName;
        int childIndex = 0;

        while ( children->next(child) )
        {
            if ( child->isNode() )
            {
                //std::cout << "  > child: " << child->getNodeKind() << " " << child->getType()->getLocalName()->c_str() << "\n";
                //std::cout.flush();

                switch ( child->getNodeKind() )
                {
                case store::StoreConsts::elementNode:
                    processElement( planState, delegatingTypeManager, schemaValidator, parent, child);
                    break;

                case store::StoreConsts::attributeNode:
                    ZORBA_ASSERT(false);
                    break;

                case store::StoreConsts::documentNode:
                    ZORBA_ASSERT(false);
                    break;

                case store::StoreConsts::textNode:
                    {
                        //std::cout << "     - text: " << child->getStringValue() << "\n"; std::cout.flush();
                        xqpStringStore_t childStringValue = child->getStringValue();
                        schemaValidator.text(childStringValue);

                        store::Item_t typeQName = schemaValidator.getTypeQName();

                        store::Item_t validatedTextNode;

                        TypeIdentifier_t typeIdentifier = TypeIdentifier::createNamedType(typeQName->getNamespace(), typeQName->getLocalName() );
                        xqtref_t xqType = delegatingTypeManager->create_type(*typeIdentifier);

                        if ( xqType!=NULL && xqType->content_kind()==XQType::SIMPLE_CONTENT_KIND )
                        {
                            store::NsBindings nsBindings;
                            parent->getNamespaceBindings(nsBindings);
                            std::vector<store::Item_t> typedValues;
                            processTextValue(planState, delegatingTypeManager, nsBindings, typeQName, childStringValue, typedValues );

                            if ( typedValues.size()==1 ) // hack around serialization bug
                                GENV_ITEMFACTORY->createTextNode(validatedTextNode, parent, typedValues[0]);
                            else
                                GENV_ITEMFACTORY->createTextNode(validatedTextNode, parent, typedValues);
                        }
                        else if ( xqType!=NULL && xqType->content_kind()==XQType::MIXED_CONTENT_KIND )
                        {
                            GENV_ITEMFACTORY->createTextNode(validatedTextNode, parent, childIndex, childStringValue);
                        }
                    }
                    break;

                case store::StoreConsts::piNode:
                    {
                        //std::cout << "     - pi: " << child->getStringValue() << "\n"; std::cout.flush();
                        store::Item_t piNode;
                        xqpStringStore_t piTarget = child->getTarget();
                        xqpStringStore_t childStringValue = child->getStringValue();
                        xqpStringStore_t childBaseUri = child->getBaseURI();
                        GENV_ITEMFACTORY->createPiNode(piNode, parent, -1, piTarget, childStringValue, childBaseUri);
                    }
                    break;

                case store::StoreConsts::commentNode:
                    {
                        //std::cout << "     - comment: " << child->getStringValue() << "\n"; std::cout.flush();
                        store::Item_t commentNode;
                        xqpStringStore_t childStringValue = child->getStringValue();
                        GENV_ITEMFACTORY->createCommentNode(commentNode, parent, -1, childStringValue);
                    }
                    break;

                case store::StoreConsts::anyNode:
                    //std::cout << "     - any: " << child->getStringValue() << "\n"; std::cout.flush();
                    ZORBA_ASSERT(false);
                    break;

                default:
                    ZORBA_ASSERT(false);
                }
            }

            childIndex++;
        }
    }

    void ValidateIterator::processNamespaces ( SchemaValidator& schemaValidator, const store::Item_t& item)
    {
        store::NsBindings bindings;
        item->getNamespaceBindings(bindings, store::StoreConsts::ONLY_LOCAL_NAMESPACES);

        for (unsigned long i = 0; i < bindings.size(); i++)
        {
            schemaValidator.ns( bindings[i].first.getStore(), bindings[i].second.getStore() );
        }
    }

    void ValidateIterator::processTextValue (PlanState& planState, DelegatingTypeManager* delegatingTypeManager,
        store::NsBindings& bindings, store::Item_t typeQName, xqpStringStore_t& textValue,
        std::vector<store::Item_t> &resultList)
    {
        xqtref_t type = delegatingTypeManager->create_named_atomic_type(typeQName, TypeConstants::QUANT_ONE);
        //std::cout << "     - processTextValue: " << typeQName->getPrefix()->str() << ":" << typeQName->getLocalName()->str() << "@" <<
        //    typeQName->getNamespace()->str() ; std::cout.flush();
        //std::cout << " type: " << ( type==NULL ? "NULL" : type->toString()) << "\n"; std::cout.flush();

        static_context* staticContext = planState.sctx();
        namespace_context nsCtx = namespace_context(staticContext, bindings);

        store::Item_t result;
        if (type!=NULL)
        {
            bool listOrUnion = false;
            if ( type->type_kind() == XQType::USER_DEFINED_KIND )
            {
                const UserDefinedXQType udXQType = static_cast<const UserDefinedXQType&>(*type);
                if ( udXQType.isList() || udXQType.isUnion() )
                {
                    listOrUnion = true;
                }
            }

            if ( listOrUnion )
            {
                xqp_string str(textValue);
                delegatingTypeManager->getSchema()->
                    parseUserSimpleTypes(str, type, resultList);
            }
            else
            {
                bool isResult = GenericCast::instance()->castToAtomic(result, textValue, type.getp(), &nsCtx);
                if ( isResult )
                    resultList.push_back(result);
            }
        }
        else
        {
            if ( GENV_ITEMFACTORY->createUntypedAtomic( result, textValue) )
                resultList.push_back(result);
        }
    }

#endif//#ifndef ZORBA_NO_XMLSCHEMA

    /* end class ValidateIterator */
}

#endif // ifndef ZORBA_NO_XMLSCHEMA
<|endoftext|>


<commit_before>#include "facepreprocessor.h"

#include <vector>
#include <algorithm>
#include <limits>
#include <cstdint>

#include <opencv2/imgproc/imgproc.hpp>

#include <QDebug>

static const double PI = std::atan(1.0) * 4;

using namespace cv;

static const bool MARK_FOUND_FEATURES = false;

FacePreprocessor::FacePreprocessor(FaceClassifiers classifiers, const Mat& input)  throw(std::invalid_argument)
    : input(input),
      result(Mat(input.rows, input.cols, CV_8UC1)),
      classifiers(classifiers)
{
    if (classifiers.face.get() == nullptr)
        throw std::invalid_argument("face classifier");
    else if (classifiers.face->empty())
        throw std::invalid_argument("face classifier");
    else if (classifiers.eye.get() == nullptr)
        throw std::invalid_argument("eye classifier");
    else if (classifiers.eye->empty())
        throw std::invalid_argument("eye classifier");
    else if (classifiers.eyePair.get() == nullptr)
        throw std::invalid_argument("eyepair classifier");
    else if (classifiers.eyePair->empty())
        throw std::invalid_argument("eyepair classifier");
    else if (classifiers.eyeLeft.get() == nullptr)
        throw std::invalid_argument("left eye classifier");
    else if (classifiers.eyeLeft->empty())
        throw std::invalid_argument("left eye classifier");
    else if (classifiers.eyeRight.get() == nullptr)
        throw std::invalid_argument("right eye classifier");
    else if (classifiers.eyeRight->empty())
        throw std::invalid_argument("right eye classifier");
}

unsigned int FacePreprocessor::GetMinSize() const
{
    int minDim = std::min(input.rows, input.cols);
    return static_cast<unsigned int>(minDim / 5.0);
}

Rect FacePreprocessor::LargestRect(const std::vector<Rect>& rects)
{
    if(rects.empty())
        return Rect();
    Rect largest = *std::max_element(rects.begin(), rects.end(), [](const Rect& a, const Rect& b)
    {
        return a.area() < b.area();
    }
    );
    return largest;
}

const double FacePreprocessor::MAX_ROTATE_ANGLE = 20.0;

double FacePreprocessor::GetRotation(cv::Rect left, cv::Rect right)
{
    Point direction;
    direction.x = right.x - left.x;
    direction.y = right.y - left.y;
    double angle = std::atan2(direction.y, direction.x) * 180.0 / PI;
    return angle;
}

std::vector<Rect> FacePreprocessor::GetEyesAlternateMethod()
{
    static std::vector<Rect> empty;
    std::vector<Rect> eyes;
    eyes.reserve(2);
    classifiers.eyePair->detectMultiScale(result, eyes, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(eyes.empty())
        return empty;
    qDebug() << "eye pair was found";
    if (MARK_FOUND_FEATURES)
        rectangle(result, eyes.front(), 1);

    std::vector<Rect> lefts;
    std::vector<Rect> rights;
    Rect cRect = eyes.front();
    cRect.width /= 2;
    classifiers.eyeLeft->detectMultiScale(result(cRect), lefts, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(lefts.empty())
    {
        qDebug () << "left wasnt found";
        return empty;
    }
    cRect.x += cRect.width;
    classifiers.eyeLeft->detectMultiScale(result(cRect), rights, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(rights.empty())
    {
        qDebug () << "right wasnt found";
        return empty;
    }
    rights.front().x += cRect.width;

    gotEyes = true;

    lefts.front().x += eyes.front().x;
    lefts.front().y += eyes.front().y;
    rights.front().x += eyes.front().x;
    rights.front().y += eyes.front().y;
    if (MARK_FOUND_FEATURES)
    {
        rectangle(result, lefts.front(), 1);
        rectangle(result, rights.front(), 1);
    }

    eyes.clear();
    eyes.push_back(lefts.front());
    eyes.push_back(rights.front());
    return eyes;
}

std::vector<Rect> FacePreprocessor::GetEyes()
{
    int maxSize = static_cast<int>(std::ceil(std::max(result.rows, result.cols) / 6.0));
    int minSize = std::max(static_cast<int>(std::floor(std::min(result.rows, result.cols) / 20.0)), 5);
    Rect upperHalfOfFace(0, 0, face.width, static_cast<int>(face.height / 1.8));
    std::vector<Rect> eyes;
    std::vector<Rect> eyePairR;
    //classifiers.eyePair->detectMultiScale(result(upperHalfOfFace), eyePairR, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(eyePairR.empty())
    {
        classifiers.eye->detectMultiScale(result(upperHalfOfFace), eyes, 1.1, 6, 0, Size(minSize, minSize), Size(maxSize, maxSize));
    }
    else
    {
        classifiers.eye->detectMultiScale(result(eyePairR.front()), eyes, 1.1, 6, 0, Size(minSize, minSize), Size(maxSize, maxSize));
        if (MARK_FOUND_FEATURES)
            rectangle(result, eyePairR.front(), 255);
    }
    for (auto eye : eyes)
    {
        if(!eyePairR.empty())
        {
            eye.x += eyePairR.front().x;
            eye.y += eyePairR.front().y;
        }
        if (MARK_FOUND_FEATURES)
            rectangle(result, eye, 1);
    }
    if(eyes.size() < 2)
    {
        qDebug() << "only" << eyes.size() << "eyes were found";
        eyes.clear();
        return eyes;
    }
    gotEyes = true;

    if(eyes.size() > 2)
    {
        // finding the pair with lowest angle
        std::vector<std::pair<uint16_t, uint16_t>> helper;
        helper.reserve(eyes.size() * eyes.size() - eyes.size());
        for(auto i = eyes.begin(); i != eyes.end(); i++)
        {
            for(auto j = eyes.begin(); j != eyes.end(); j++)
            {
                if (i != j)
                    helper.push_back(std::make_pair(std::distance(eyes.begin(), i), std::distance(eyes.begin(), j)));
            }
        }

        std::sort(helper.begin(), helper.end(), [&eyes](const std::pair<uint16_t, uint16_t>& a, const std::pair<uint16_t, uint16_t>& b)
        {
            double angleA = std::abs(GetRotation(eyes[a.first], eyes[a.second]));
            double angleB = std::abs(GetRotation(eyes[b.first], eyes[b.second]));
            return angleA < angleB;
        });

        assert(helper.front().first != helper.front().second);

        std::swap(eyes[0], eyes[helper.front().first]);
        std::swap(eyes[1], eyes[helper.front().second]);
    }

    std::sort(eyes.begin(), eyes.begin() + 2, [](const Rect& a, const Rect& b) { return a.x < b.x; });
    eyes.resize(2);
    return eyes;
}

void FacePreprocessor::RotateFace()
{
    std::vector<Rect> eyes = GetEyes();
    if(eyes.size() < 2)
    {
        return;
    }

    double angle = GetRotation(eyes[0], eyes[1]);
    qDebug() << "rotation angle: " << angle;
    if (std::abs(angle) < std::numeric_limits<double>::epsilon() * 3 || std::abs(angle) > MAX_ROTATE_ANGLE)
        return;

    int size = std::max(result.cols, result.rows);
    int fullSize = std::max(normalized.cols, normalized.rows);
    Point2f pt(size/2.0f + face.x, size/2.0f + face.y);
    Mat r = getRotationMatrix2D(pt, angle, 1.0);

    warpAffine(normalized, rotated, r, Size(fullSize, fullSize), CV_INTER_LANCZOS4);

    result = rotated(face);
}

void FacePreprocessor::ScaleFace()
{
    Rect aspected = face;
    if(face.width < face.height)
    {
        aspected.width = face.height;
    }
    else
    {
        aspected.height = face.width;
    }

    Mat scaled = result.clone();

    copyMakeBorder(scaled, scaled, 0, aspected.height, 0, aspected.width, BORDER_REPLICATE);

    aspected.x = 0;
    aspected.y = 0;

    result = scaled(aspected);
    resize(result, result, Size(512, 512), 0.0, 0.0, CV_INTER_LANCZOS4);
}

double FacePreprocessor::GetAccuracy() const
{
    double accuracy = 0.0;
    if(face.width > 0 && face.height > 0)
        accuracy += 0.5;
    if(gotEyes)
        accuracy += 0.5;
    return accuracy;
}

Mat FacePreprocessor::Preprocess() throw (NoFaceFoundException)
{
    if(input.type() == CV_8UC3)
        cvtColor(input, result, CV_BGR2GRAY);
    else
        result = input;
    equalizeHist(result, normalized);

    result = normalized;

    std::vector<Rect> faces;
    Size minSize(GetMinSize(), GetMinSize());
    classifiers.face->detectMultiScale(result, faces, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT, minSize);

    if (!faces.empty())
    {
        face = LargestRect(faces);

        result = result(face);
    }
    else
    {
        throw NoFaceFoundException();
    }

    RotateFace();

    static uint64_t cntr = 0;
    static uint64_t cntr2 = 0;

    cntr2++;

    if(!gotEyes)
        qDebug() << "no eyes were found on the face -- this is odd :(" << ++cntr << "/" << cntr2;
    else
        qDebug() << "is rotated? " << !rotated.empty() << (cntr2 - cntr) << "/" << cntr2;

    ScaleFace();

    return result;
}
<commit_msg>intersecting found eyes are removed<commit_after>#include "facepreprocessor.h"

#include <vector>
#include <algorithm>
#include <limits>
#include <cstdint>

#include <opencv2/imgproc/imgproc.hpp>

#include <QDebug>

static const double PI = std::atan(1.0) * 4;

using namespace cv;

static const bool MARK_FOUND_FEATURES = false;

FacePreprocessor::FacePreprocessor(FaceClassifiers classifiers, const Mat& input)  throw(std::invalid_argument)
    : input(input),
      result(Mat(input.rows, input.cols, CV_8UC1)),
      classifiers(classifiers)
{
    if (classifiers.face.get() == nullptr)
        throw std::invalid_argument("face classifier");
    else if (classifiers.face->empty())
        throw std::invalid_argument("face classifier");
    else if (classifiers.eye.get() == nullptr)
        throw std::invalid_argument("eye classifier");
    else if (classifiers.eye->empty())
        throw std::invalid_argument("eye classifier");
    else if (classifiers.eyePair.get() == nullptr)
        throw std::invalid_argument("eyepair classifier");
    else if (classifiers.eyePair->empty())
        throw std::invalid_argument("eyepair classifier");
    else if (classifiers.eyeLeft.get() == nullptr)
        throw std::invalid_argument("left eye classifier");
    else if (classifiers.eyeLeft->empty())
        throw std::invalid_argument("left eye classifier");
    else if (classifiers.eyeRight.get() == nullptr)
        throw std::invalid_argument("right eye classifier");
    else if (classifiers.eyeRight->empty())
        throw std::invalid_argument("right eye classifier");
}

unsigned int FacePreprocessor::GetMinSize() const
{
    int minDim = std::min(input.rows, input.cols);
    return static_cast<unsigned int>(minDim / 5.0);
}

Rect FacePreprocessor::LargestRect(const std::vector<Rect>& rects)
{
    if(rects.empty())
        return Rect();
    Rect largest = *std::max_element(rects.begin(), rects.end(), [](const Rect& a, const Rect& b)
    {
        return a.area() < b.area();
    }
    );
    return largest;
}

const double FacePreprocessor::MAX_ROTATE_ANGLE = 20.0;

double FacePreprocessor::GetRotation(cv::Rect left, cv::Rect right)
{
    Point direction;
    direction.x = right.x - left.x;
    direction.y = right.y - left.y;
    double angle = std::atan2(direction.y, direction.x) * 180.0 / PI;
    return angle;
}

std::vector<Rect> FacePreprocessor::GetEyesAlternateMethod()
{
    static std::vector<Rect> empty;
    std::vector<Rect> eyes;
    eyes.reserve(2);
    classifiers.eyePair->detectMultiScale(result, eyes, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(eyes.empty())
        return empty;
    qDebug() << "eye pair was found";
    if (MARK_FOUND_FEATURES)
        rectangle(result, eyes.front(), 1);

    std::vector<Rect> lefts;
    std::vector<Rect> rights;
    Rect cRect = eyes.front();
    cRect.width /= 2;
    classifiers.eyeLeft->detectMultiScale(result(cRect), lefts, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(lefts.empty())
    {
        qDebug () << "left wasnt found";
        return empty;
    }
    cRect.x += cRect.width;
    classifiers.eyeLeft->detectMultiScale(result(cRect), rights, 1.1, 4, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(rights.empty())
    {
        qDebug () << "right wasnt found";
        return empty;
    }
    rights.front().x += cRect.width;

    gotEyes = true;

    lefts.front().x += eyes.front().x;
    lefts.front().y += eyes.front().y;
    rights.front().x += eyes.front().x;
    rights.front().y += eyes.front().y;
    if (MARK_FOUND_FEATURES)
    {
        rectangle(result, lefts.front(), 1);
        rectangle(result, rights.front(), 1);
    }

    eyes.clear();
    eyes.push_back(lefts.front());
    eyes.push_back(rights.front());
    return eyes;
}

std::vector<Rect> FacePreprocessor::GetEyes()
{
    int maxSize = static_cast<int>(std::ceil(std::max(result.rows, result.cols) / 6.0));
    int minSize = std::max(static_cast<int>(std::floor(std::min(result.rows, result.cols) / 20.0)), 5);
    Rect upperHalfOfFace(0, 0, face.width, static_cast<int>(face.height / 1.8));
    std::vector<Rect> eyes;
    std::vector<Rect> eyePairR;
    //classifiers.eyePair->detectMultiScale(result(upperHalfOfFace), eyePairR, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT);
    if(eyePairR.empty())
    {
        classifiers.eye->detectMultiScale(result(upperHalfOfFace), eyes, 1.1, 6, 0, Size(minSize, minSize), Size(maxSize, maxSize));
    }
    else
    {
        classifiers.eye->detectMultiScale(result(eyePairR.front()), eyes, 1.1, 6, 0, Size(minSize, minSize), Size(maxSize, maxSize));
        if (MARK_FOUND_FEATURES)
            rectangle(result, eyePairR.front(), 255);
    }
    for (auto eye : eyes)
    {
        if(!eyePairR.empty())
        {
            eye.x += eyePairR.front().x;
            eye.y += eyePairR.front().y;
        }
        if (MARK_FOUND_FEATURES)
            rectangle(result, eye, 1);
    }
    if(eyes.size() < 2)
    {
        qDebug() << "only" << eyes.size() << "eyes were found";
        eyes.clear();
        return eyes;
    }
    gotEyes = true;

    for(uint8_t i = 0; i < eyes.size(); i++)
    {
        for(uint8_t j = 0; j < eyes.size(); j++)
        {
            if (i != j)
            {
                Rect intersection = eyes[i] & eyes[j];
                if (intersection.area() > 0)
                {
                    eyes.erase(eyes.begin() + j);
                    if (i > j)
                        i--;
                    j--;
                }
            }
        }
    }

    if(eyes.size() > 2)
    {
        // finding the pair with lowest angle
        std::vector<std::pair<uint16_t, uint16_t>> helper;
        helper.reserve(eyes.size() * eyes.size() - eyes.size());
        for(auto i = eyes.begin(); i != eyes.end(); i++)
        {
            for(auto j = eyes.begin(); j != eyes.end(); j++)
            {
                if (i != j)
                    helper.push_back(std::make_pair(std::distance(eyes.begin(), i), std::distance(eyes.begin(), j)));
            }
        }

        std::sort(helper.begin(), helper.end(), [&eyes](const std::pair<uint16_t, uint16_t>& a, const std::pair<uint16_t, uint16_t>& b)
        {
            double angleA = std::abs(GetRotation(eyes[a.first], eyes[a.second]));
            double angleB = std::abs(GetRotation(eyes[b.first], eyes[b.second]));
            return angleA < angleB;
        });

        assert(helper.front().first != helper.front().second);

        std::swap(eyes[0], eyes[helper.front().first]);
        std::swap(eyes[1], eyes[helper.front().second]);
    }

    std::sort(eyes.begin(), eyes.begin() + 2, [](const Rect& a, const Rect& b) { return a.x < b.x; });
    eyes.resize(2);
    return eyes;
}

void FacePreprocessor::RotateFace()
{
    std::vector<Rect> eyes = GetEyes();
    if(eyes.size() < 2)
    {
        return;
    }

    double angle = GetRotation(eyes[0], eyes[1]);
    qDebug() << "rotation angle: " << angle;
    if (std::abs(angle) < std::numeric_limits<double>::epsilon() * 3 || std::abs(angle) > MAX_ROTATE_ANGLE)
        return;

    int size = std::max(result.cols, result.rows);
    int fullSize = std::max(normalized.cols, normalized.rows);
    Point2f pt(size/2.0f + face.x, size/2.0f + face.y);
    Mat r = getRotationMatrix2D(pt, angle, 1.0);

    warpAffine(normalized, rotated, r, Size(fullSize, fullSize), CV_INTER_LANCZOS4);

    result = rotated(face);
}

void FacePreprocessor::ScaleFace()
{
    Rect aspected = face;
    if(face.width < face.height)
    {
        aspected.width = face.height;
    }
    else
    {
        aspected.height = face.width;
    }

    Mat scaled = result.clone();

    copyMakeBorder(scaled, scaled, 0, aspected.height, 0, aspected.width, BORDER_REPLICATE);

    aspected.x = 0;
    aspected.y = 0;

    result = scaled(aspected);
    resize(result, result, Size(512, 512), 0.0, 0.0, CV_INTER_LANCZOS4);
}

double FacePreprocessor::GetAccuracy() const
{
    double accuracy = 0.0;
    if(face.width > 0 && face.height > 0)
        accuracy += 0.5;
    if(gotEyes)
        accuracy += 0.5;
    return accuracy;
}

Mat FacePreprocessor::Preprocess() throw (NoFaceFoundException)
{
    if(input.type() == CV_8UC3)
        cvtColor(input, result, CV_BGR2GRAY);
    else
        result = input;
    equalizeHist(result, normalized);

    result = normalized;

    std::vector<Rect> faces;
    Size minSize(GetMinSize(), GetMinSize());
    classifiers.face->detectMultiScale(result, faces, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT, minSize);

    if (!faces.empty())
    {
        face = LargestRect(faces);

        result = result(face);
    }
    else
    {
        throw NoFaceFoundException();
    }

    RotateFace();

    static uint64_t cntr = 0;
    static uint64_t cntr2 = 0;

    cntr2++;

    if(!gotEyes)
        qDebug() << "no eyes were found on the face -- this is odd :(" << ++cntr << "/" << cntr2;
    else
        qDebug() << "is rotated? " << !rotated.empty() << (cntr2 - cntr) << "/" << cntr2;

    ScaleFace();

    return result;
}
<|endoftext|>


<commit_before>#ifndef DEDICATED_ONLY

#include "sound_sample_openal.h"
#include "gusanos/resource_list.h"
#include "CGameObject.h"
#include "gusanos/allegro.h"

#ifdef __APPLE__
#ifndef __MACOSX__
#define __MACOSX__
#endif
#endif

#include <vorbis/vorbisfile.h>
#include <AL/al.h>
#include <AL/alut.h>
#include <stdio.h>
#include <vector>
#include <string>
#include <iostream>
#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string.hpp>
namespace fs = boost::filesystem;

using namespace std;

namespace
{
	const int BUFFER_SIZE = 32768;       // 32 KB buffers
}

// This function loads a .ogg file into a memory buffer and returns
// the format and frequency.
void LoadOGG(const char *fileName, vector<char> &buffer, ALenum &format, ALsizei &freq)
    {
    int endian = 0;                         // 0 for Little-Endian, 1 for Big-Endian
    int bitStream;
    long bytes;
    char array[BUFFER_SIZE];                // Local fixed size array
    FILE *f;

    // Open for binary reading
    f = OpenGameFile(fileName, "rb");

    if (f == NULL)
        {
        //cerr << "Cannot open " << fileName << " for reading..." << endl;
        throw -1;
        }
    // end if

    vorbis_info *pInfo;
    OggVorbis_File oggFile;

    // Try opening the given file
    if (ov_open(f, &oggFile, NULL, 0) != 0)
        {
        cerr << "Error opening " << fileName << " for decoding..." << endl;
        throw -1;
        }
    // end if

    // Get some information about the OGG file
    pInfo = ov_info(&oggFile, -1);

    // Check the number of channels... always use 16-bit samples
    if (pInfo->channels == 1)
        format = AL_FORMAT_MONO16;
    else
        format = AL_FORMAT_STEREO16;
    // end if

    // The frequency of the sampling rate
    freq = pInfo->rate;

    // Keep reading until all is read
    do
        {
        // Read up to a buffer's worth of decoded sound data
        bytes = ov_read(&oggFile, array, BUFFER_SIZE, endian, 2, 1, &bitStream);

        if (bytes < 0)
            {
            ov_clear(&oggFile);
            cerr << "Error decoding " << fileName << "..." << endl;
        throw -1;
            }
        // end if

        // Append to end of buffer
        buffer.insert(buffer.end(), array, array + bytes);
        }
    while (bytes > 0);

    // Clean up!
    ov_clear(&oggFile);
    }
// end of LoadOGG

ALuint  LoadSoundFromFile( const char* inSoundFile )
{
    ALuint bufferID;                        // The OpenAL sound buffer ID
    ALenum format;                          // The sound data format
    ALsizei freq;                           // The frequency of the sound data
    vector<char> bufferData;                // The sound buffer data from file

    // Create sound buffer and source
    alGenBuffers(1, &bufferID);

	try{
    // Load the OGG file into memory
    LoadOGG(inSoundFile, bufferData, format, freq);
	}
	catch
	 (int) {
		return 0;
	}
    // Upload sound data to buffer
    alBufferData(bufferID, format, &bufferData[0], static_cast<ALsizei>(bufferData.size()), freq);
    return bufferID;

}

SoundSampleOpenAL::SoundSampleOpenAL(std::string const& filename):SoundSample(filename)
{
    ALuint bufferID;                        // The OpenAL sound buffer ID
	string name = filename;

	if (boost::iends_with(name, ".ogg"))
	{
		bufferID=LoadSoundFromFile( name.c_str());
		if (bufferID==0)
		{
			m_sound=0;
			return;
		}
	}
	else
	{
		bufferID=alutCreateBufferFromFile (GetFullFileName(name).c_str());
		if (bufferID==AL_NONE)
		{
			m_sound=0;
			return;
		}
	}
    ALuint sourceID;                        // The OpenAL sound source
    alGenSources(1, &sourceID);
    // Attach sound buffer to source
    alSourcei(sourceID, AL_BUFFER, bufferID);
	alSourcef(	 sourceID,AL_ROLLOFF_FACTOR,2);
	alSourcef(sourceID,AL_GAIN,0.7f);
	//alSourcef(	 mALSource,AL_REFERENCE_DISTANCE,20);
    /*alSource3f(mALSource, AL_POSITION,        0.0, 0.0, 0.0);
    alSource3f(mALSource, AL_VELOCITY,        0.0, 0.0, 0.0);
    alSource3f(mALSource, AL_DIRECTION,       0.0, 0.0, 0.0);
    alSourcef (mALSource, AL_ROLLOFF_FACTOR,  0.0          );
    alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_TRUE      );*/
	m_sound=sourceID ;

}

SoundSampleOpenAL::~SoundSampleOpenAL()
{
	if ( m_sound)
	{
		ALint mALBufferi;
		alGetSourcei(m_sound, AL_BUFFER ,&mALBufferi);
		ALuint mALBufferu = (ALuint )mALBufferi;
		alDeleteBuffers(1,&mALBufferu);
		alDeleteSources(1,&m_sound);
	}

}

bool SoundSampleOpenAL::avail()
{
	return (m_sound!=0);
}

void SoundSampleOpenAL::play( float pitch,float volume)
{
	if( m_sound )
	{
		//cout<<"Play "<<endl;

		float _pos[3];
		alGetListenerfv(AL_POSITION, _pos);
		_pos[2] = 0;

		alSourcefv( m_sound , AL_POSITION, _pos);
		alSourcef(	 m_sound ,AL_REFERENCE_DISTANCE,100.0/100*50); //ok?

		alSourcef(	 m_sound ,AL_PITCH,pitch);
		alSourcef(	 m_sound ,AL_GAIN,volume );
		alSourcePlay( m_sound) ;
	}
}

void SoundSampleOpenAL::play2D(const Vec& pos, float loudness, float pitch)
{
	if( m_sound )
	{
		//cout<<"Play 2D"<<endl;
			float _pos[3] = { pos.x, pos.y, 0 };
			//cout<<"sound: x,y: "<<pos.x<<" "<<pos.y<<endl;
			alSourcefv( m_sound , AL_POSITION, _pos);
			alSourcef(	 m_sound ,AL_PITCH,pitch);
			alSourcef(	 m_sound ,AL_REFERENCE_DISTANCE,loudness/100*50); //ok?
			alSourcePlay( m_sound) ;
	}
}

void SoundSampleOpenAL::play2D(CGameObject* obj, float loudness, float pitch)
{
	//cout<<"Play 2d(obj)"<<endl;
	Vec pos( obj->pos().x, obj->pos().y) ;
	play2D(pos,loudness, pitch);

}

bool SoundSampleOpenAL::isValid()
{
	ALint state;
	alGetSourcei(m_sound,AL_SOURCE_STATE,&state);
	if (state==AL_PLAYING)
	{
		return true;
	}
	return false; //I think
}

void SoundSampleOpenAL::updateObjSound(Vec& vec)
{
	ALfloat pos[3] = { vec.x, vec.y, 0 };
	alSourcefv( m_sound , AL_POSITION, pos);

}

#endif
<commit_msg>we also need native filenames here<commit_after>#ifndef DEDICATED_ONLY

#include "sound_sample_openal.h"
#include "gusanos/resource_list.h"
#include "CGameObject.h"
#include "gusanos/allegro.h"

#ifdef __APPLE__
#ifndef __MACOSX__
#define __MACOSX__
#endif
#endif

#include <vorbis/vorbisfile.h>
#include <AL/al.h>
#include <AL/alut.h>
#include <stdio.h>
#include <vector>
#include <string>
#include <iostream>
#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string.hpp>
namespace fs = boost::filesystem;

using namespace std;

namespace
{
	const int BUFFER_SIZE = 32768;       // 32 KB buffers
}

// This function loads a .ogg file into a memory buffer and returns
// the format and frequency.
void LoadOGG(const char *fileName, vector<char> &buffer, ALenum &format, ALsizei &freq)
    {
    int endian = 0;                         // 0 for Little-Endian, 1 for Big-Endian
    int bitStream;
    long bytes;
    char array[BUFFER_SIZE];                // Local fixed size array
    FILE *f;

    // Open for binary reading
    f = OpenGameFile(fileName, "rb");

    if (f == NULL)
        {
        //cerr << "Cannot open " << fileName << " for reading..." << endl;
        throw -1;
        }
    // end if

    vorbis_info *pInfo;
    OggVorbis_File oggFile;

    // Try opening the given file
    if (ov_open(f, &oggFile, NULL, 0) != 0)
        {
        cerr << "Error opening " << fileName << " for decoding..." << endl;
        throw -1;
        }
    // end if

    // Get some information about the OGG file
    pInfo = ov_info(&oggFile, -1);

    // Check the number of channels... always use 16-bit samples
    if (pInfo->channels == 1)
        format = AL_FORMAT_MONO16;
    else
        format = AL_FORMAT_STEREO16;
    // end if

    // The frequency of the sampling rate
    freq = pInfo->rate;

    // Keep reading until all is read
    do
        {
        // Read up to a buffer's worth of decoded sound data
        bytes = ov_read(&oggFile, array, BUFFER_SIZE, endian, 2, 1, &bitStream);

        if (bytes < 0)
            {
            ov_clear(&oggFile);
            cerr << "Error decoding " << fileName << "..." << endl;
        throw -1;
            }
        // end if

        // Append to end of buffer
        buffer.insert(buffer.end(), array, array + bytes);
        }
    while (bytes > 0);

    // Clean up!
    ov_clear(&oggFile);
    }
// end of LoadOGG

ALuint  LoadSoundFromFile( const char* inSoundFile )
{
    ALuint bufferID;                        // The OpenAL sound buffer ID
    ALenum format;                          // The sound data format
    ALsizei freq;                           // The frequency of the sound data
    vector<char> bufferData;                // The sound buffer data from file

    // Create sound buffer and source
    alGenBuffers(1, &bufferID);

	try{
    // Load the OGG file into memory
    LoadOGG(inSoundFile, bufferData, format, freq);
	}
	catch
	 (int) {
		return 0;
	}
    // Upload sound data to buffer
    alBufferData(bufferID, format, &bufferData[0], static_cast<ALsizei>(bufferData.size()), freq);
    return bufferID;

}

SoundSampleOpenAL::SoundSampleOpenAL(std::string const& filename):SoundSample(filename)
{
    ALuint bufferID;                        // The OpenAL sound buffer ID
	string name = filename;

	if (boost::iends_with(name, ".ogg"))
	{
		bufferID=LoadSoundFromFile( name.c_str());
		if (bufferID==0)
		{
			m_sound=0;
			return;
		}
	}
	else
	{
		bufferID=alutCreateBufferFromFile (Utf8ToSystemNative(GetFullFileName(name)).c_str());
		if (bufferID==AL_NONE)
		{
			m_sound=0;
			return;
		}
	}
    ALuint sourceID;                        // The OpenAL sound source
    alGenSources(1, &sourceID);
    // Attach sound buffer to source
    alSourcei(sourceID, AL_BUFFER, bufferID);
	alSourcef(	 sourceID,AL_ROLLOFF_FACTOR,2);
	alSourcef(sourceID,AL_GAIN,0.7f);
	//alSourcef(	 mALSource,AL_REFERENCE_DISTANCE,20);
    /*alSource3f(mALSource, AL_POSITION,        0.0, 0.0, 0.0);
    alSource3f(mALSource, AL_VELOCITY,        0.0, 0.0, 0.0);
    alSource3f(mALSource, AL_DIRECTION,       0.0, 0.0, 0.0);
    alSourcef (mALSource, AL_ROLLOFF_FACTOR,  0.0          );
    alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_TRUE      );*/
	m_sound=sourceID ;

}

SoundSampleOpenAL::~SoundSampleOpenAL()
{
	if ( m_sound)
	{
		ALint mALBufferi;
		alGetSourcei(m_sound, AL_BUFFER ,&mALBufferi);
		ALuint mALBufferu = (ALuint )mALBufferi;
		alDeleteBuffers(1,&mALBufferu);
		alDeleteSources(1,&m_sound);
	}

}

bool SoundSampleOpenAL::avail()
{
	return (m_sound!=0);
}

void SoundSampleOpenAL::play( float pitch,float volume)
{
	if( m_sound )
	{
		//cout<<"Play "<<endl;

		float _pos[3];
		alGetListenerfv(AL_POSITION, _pos);
		_pos[2] = 0;

		alSourcefv( m_sound , AL_POSITION, _pos);
		alSourcef(	 m_sound ,AL_REFERENCE_DISTANCE,100.0/100*50); //ok?

		alSourcef(	 m_sound ,AL_PITCH,pitch);
		alSourcef(	 m_sound ,AL_GAIN,volume );
		alSourcePlay( m_sound) ;
	}
}

void SoundSampleOpenAL::play2D(const Vec& pos, float loudness, float pitch)
{
	if( m_sound )
	{
		//cout<<"Play 2D"<<endl;
			float _pos[3] = { pos.x, pos.y, 0 };
			//cout<<"sound: x,y: "<<pos.x<<" "<<pos.y<<endl;
			alSourcefv( m_sound , AL_POSITION, _pos);
			alSourcef(	 m_sound ,AL_PITCH,pitch);
			alSourcef(	 m_sound ,AL_REFERENCE_DISTANCE,loudness/100*50); //ok?
			alSourcePlay( m_sound) ;
	}
}

void SoundSampleOpenAL::play2D(CGameObject* obj, float loudness, float pitch)
{
	//cout<<"Play 2d(obj)"<<endl;
	Vec pos( obj->pos().x, obj->pos().y) ;
	play2D(pos,loudness, pitch);

}

bool SoundSampleOpenAL::isValid()
{
	ALint state;
	alGetSourcei(m_sound,AL_SOURCE_STATE,&state);
	if (state==AL_PLAYING)
	{
		return true;
	}
	return false; //I think
}

void SoundSampleOpenAL::updateObjSound(Vec& vec)
{
	ALfloat pos[3] = { vec.x, vec.y, 0 };
	alSourcefv( m_sound , AL_POSITION, pos);

}

#endif
<|endoftext|>


<commit_before>/*
    Copyright 2008 Brain Research Institute, Melbourne, Australia

    Written by J-Donald Tournier, 27/06/08.

    This file is part of MRtrix.

    MRtrix is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    MRtrix is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "command.h"
#include "image/header.h"
#include "file/nifti1_utils.h"
#include "math/matrix.h"
#include "math/LU.h"

using namespace MR;
using namespace App;

void usage ()
{
  DESCRIPTION
  + "edit transformations."

  + "Currently, this command's only function is to convert the transformation matrix provided "
    "by FSL's flirt command to a format usable in MRtrix.";

  ARGUMENTS
  + Argument ("input", "input transformation matrix").type_file_in ()
  + Argument ("output", "the output transformation matrix.").type_file_out ();

  OPTIONS
    + Option ("flirt_import",
        "convert a transformation matrix produced by FSL's flirt command into a format usable by MRtrix. "
        "You'll need to provide as additional arguments the save NIfTI images that were passed to flirt "
        "with the -in and -ref options.")
    + Argument ("in").type_image_in ()
    + Argument ("ref").type_image_in ();
}

Math::Matrix<float> get_flirt_transform (const Image::Header& header)
{
  std::vector<size_t> axes;
  Math::Matrix<float> nifti_transform = File::NIfTI::adjust_transform (header, axes);
  if (Math::LU::sgndet (nifti_transform) < 0.0)
    return nifti_transform;

  Math::Matrix<float> coord_switch (4,4);
  coord_switch.identity();
  coord_switch(0,0) = -1.0f;
  coord_switch(0,3) = (header.dim(axes[0])-1) * header.vox(axes[0]);

  Math::Matrix<float> updated_transform;
  return Math::mult (updated_transform, nifti_transform, coord_switch);
}

inline void cleanup_4x4_transform (Math::Matrix<float>& transform)
{
  transform(3,0) = transform(3,1) = transform(3,2) = 0.0f;
  transform(3,3) = 1.0f;
}

void run ()
{
  Math::Matrix<float> transform;
  transform.load (argument[0]);

  Options opt = get_options ("flirt_import");
  if (opt.size()) {
    Image::Header src_header (opt[0][0]);
    Math::Matrix<float> src_flirt_to_scanner = get_flirt_transform (src_header);

    Image::Header dest_header (opt[0][1]);
    Math::Matrix<float> dest_flirt_to_scanner = get_flirt_transform (dest_header);

    Math::Matrix<float> scanner_to_src_flirt = Math::LU::inv (src_flirt_to_scanner);

    Math::Matrix<float> scanner_to_transformed_dest_flirt;
    Math::mult (scanner_to_transformed_dest_flirt, transform, scanner_to_src_flirt);

    Math::mult (transform, dest_flirt_to_scanner, scanner_to_transformed_dest_flirt);
  }

  cleanup_4x4_transform (transform);

  transform.save (argument[1]);
}

<commit_msg>modified transformcalc flirt conversion to a reverse mapping (from template to moving)<commit_after>/*
    Copyright 2008 Brain Research Institute, Melbourne, Australia

    Written by J-Donald Tournier, 27/06/08.

    This file is part of MRtrix.

    MRtrix is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    MRtrix is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "command.h"
#include "image/header.h"
#include "file/nifti1_utils.h"
#include "math/matrix.h"
#include "math/LU.h"

using namespace MR;
using namespace App;

void usage ()
{
  DESCRIPTION
  + "edit transformations."

  + "Currently, this command's only function is to convert the transformation matrix provided "
    "by FSL's flirt command to a format usable in MRtrix.";

  ARGUMENTS
  + Argument ("input", "input transformation matrix").type_file_in ()
  + Argument ("output", "the output transformation matrix.").type_file_out ();

  OPTIONS
    + Option ("flirt_import",
        "convert a transformation matrix produced by FSL's flirt command into a format usable by MRtrix. "
        "You'll need to provide as additional arguments the save NIfTI images that were passed to flirt "
        "with the -in and -ref options.")
    + Argument ("in").type_image_in ()
    + Argument ("ref").type_image_in ();
}

Math::Matrix<float> get_flirt_transform (const Image::Header& header)
{
  std::vector<size_t> axes;
  Math::Matrix<float> nifti_transform = File::NIfTI::adjust_transform (header, axes);
  if (Math::LU::sgndet (nifti_transform) < 0.0)
    return nifti_transform;

  Math::Matrix<float> coord_switch (4,4);
  coord_switch.identity();
  coord_switch(0,0) = -1.0f;
  coord_switch(0,3) = (header.dim(axes[0])-1) * header.vox(axes[0]);

  Math::Matrix<float> updated_transform;
  return Math::mult (updated_transform, nifti_transform, coord_switch);
}

inline void cleanup_4x4_transform (Math::Matrix<float>& transform)
{
  transform(3,0) = transform(3,1) = transform(3,2) = 0.0f;
  transform(3,3) = 1.0f;
}

void run ()
{
  Math::Matrix<float> transform;
  transform.load (argument[0]);

  Options opt = get_options ("flirt_import");
  if (opt.size()) {
    Image::Header src_header (opt[0][0]);
    Math::Matrix<float> src_flirt_to_scanner = get_flirt_transform (src_header);

    Image::Header dest_header (opt[0][1]);
    Math::Matrix<float> dest_flirt_to_scanner = get_flirt_transform (dest_header);

    Math::Matrix<float> scanner_to_src_flirt = Math::LU::inv (src_flirt_to_scanner);

    Math::Matrix<float> scanner_to_transformed_dest_flirt;
    Math::mult (scanner_to_transformed_dest_flirt, transform, scanner_to_src_flirt);

    Math::Matrix<float> forward_transform;
    Math::mult (forward_transform, dest_flirt_to_scanner, scanner_to_transformed_dest_flirt);

    transform = Math::LU::inv (forward_transform);
  }

  cleanup_4x4_transform (transform);

  transform.save (argument[1]);
}

<|endoftext|>


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

#pragma hdrstop

#ifndef _SVTOOLS_CTLOPTIONS_HXX
#include "ctloptions.hxx"
#endif
#ifndef _UTL_CONFIGITEM_HXX_
#include <unotools/configitem.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_ANY_H_
#include <com/sun/star/uno/Any.h>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

using namespace ::com::sun::star::uno;

#define ASCII_STR(s)    rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(s) )

// SvtCJKOptions_Impl ----------------------------------------------------------

class SvtCTLOptions_Impl : public utl::ConfigItem
{
private:
    static Sequence< rtl::OUString > m_aPropertyNames;

    sal_Bool    m_bIsLoaded;
    sal_Bool    m_bCTLFontEnabled;
    sal_Bool    m_bCTLSequenceChecking;

public:
    SvtCTLOptions_Impl();
    ~SvtCTLOptions_Impl();

    virtual void    Notify( const Sequence< rtl::OUString >& _aPropertyNames );
    virtual void    Commit();
    void            Load();

    sal_Bool        IsLoaded() { return m_bIsLoaded; }
    void            SetCTLFontEnabled( sal_Bool _bEnabled );
    sal_Bool        IsCTLFontEnabled() const { return m_bCTLFontEnabled; }

    void            SetCTLSequenceChecking( sal_Bool _bEnabled );
    sal_Bool        IsCTLSequenceChecking() const { return m_bCTLSequenceChecking;}
};
//------------------------------------------------------------------------------
Sequence< rtl::OUString > SvtCTLOptions_Impl::m_aPropertyNames;
//------------------------------------------------------------------------------
SvtCTLOptions_Impl::SvtCTLOptions_Impl() :

    utl::ConfigItem( ASCII_STR("Office.Common/I18N/CTL") ),

    m_bIsLoaded         ( sal_False ),
    m_bCTLFontEnabled   ( sal_False ),
    m_bCTLSequenceChecking( sal_False )

{
}
//------------------------------------------------------------------------------
SvtCTLOptions_Impl::~SvtCTLOptions_Impl()
{
}
// -----------------------------------------------------------------------------
void SvtCTLOptions_Impl::Notify( const Sequence< rtl::OUString >& aPropertyNames )
{
    Load();
}
// -----------------------------------------------------------------------------
void SvtCTLOptions_Impl::Commit()
{
    rtl::OUString* pNames = m_aPropertyNames.getArray();
    Sequence< Any > aValues( m_aPropertyNames.getLength() );
    Any* pValues = aValues.getArray();

    const Type& rType = ::getBooleanCppuType();
    BOOL bVal;
    for ( int nProp = 0; nProp < m_aPropertyNames.getLength(); nProp++ )
    {
        switch( nProp )
        {
            case 0: bVal = m_bCTLFontEnabled; break;
            case 1: bVal = m_bCTLSequenceChecking; break;
        }
        pValues[nProp].setValue( &bVal, getBooleanCppuType() );
    }
    PutProperties( m_aPropertyNames, aValues );
}
// -----------------------------------------------------------------------------
void SvtCTLOptions_Impl::Load()
{
    if ( !m_aPropertyNames.getLength() )
    {
        m_aPropertyNames.realloc(2);
        rtl::OUString* pNames = m_aPropertyNames.getArray();
        pNames[0] = ASCII_STR("CTLFont");
        pNames[1] = ASCII_STR("CTLSequenceChecking");
        EnableNotification( m_aPropertyNames );
    }
    Sequence< Any > aValues = GetProperties( m_aPropertyNames );
    const Any* pValues = aValues.getConstArray();
    DBG_ASSERT( aValues.getLength() == m_aPropertyNames.getLength(), "GetProperties failed" );
    if ( aValues.getLength() == m_aPropertyNames.getLength() )
    {
        sal_Bool bValue = sal_False;

        for ( int nProp = 0; nProp < m_aPropertyNames.getLength(); nProp++ )
        {
            if ( pValues[nProp].hasValue() )
            {
                if ( pValues[nProp] >>= bValue )
                {
                    switch ( nProp )
                    {
                        case 0: m_bCTLFontEnabled = bValue; break;
                        case 1: m_bCTLSequenceChecking = bValue;break;
                    }
                }
            }
        }
    }
    m_bIsLoaded = sal_True;
}
//------------------------------------------------------------------------------
void SvtCTLOptions_Impl::SetCTLFontEnabled( sal_Bool _bEnabled )
{
    if(m_bCTLFontEnabled != _bEnabled)
    {
        m_bCTLFontEnabled = _bEnabled;
        SetModified();
    }
}
//------------------------------------------------------------------------------
void SvtCTLOptions_Impl::SetCTLSequenceChecking( sal_Bool _bEnabled )
{
    if(m_bCTLSequenceChecking != _bEnabled)
    {
        SetModified();
        m_bCTLSequenceChecking = _bEnabled;
    }
}
// global ----------------------------------------------------------------

static SvtCTLOptions_Impl*  pCTLOptions = NULL;
static sal_Int32            nCTLRefCount = 0;
static ::osl::Mutex         aCTLMutex;

// class SvtCTLOptions --------------------------------------------------

SvtCTLOptions::SvtCTLOptions( sal_Bool bDontLoad )
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( aCTLMutex );
    if ( !pCTLOptions )
        pCTLOptions = new SvtCTLOptions_Impl;
    if( !bDontLoad && !pCTLOptions->IsLoaded() )
        pCTLOptions->Load();

    ++nCTLRefCount;
    m_pImp = pCTLOptions;
}

// -----------------------------------------------------------------------

SvtCTLOptions::~SvtCTLOptions()
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( aCTLMutex );

    if ( !--nCTLRefCount )
        DELETEZ( pCTLOptions );
}
// -----------------------------------------------------------------------------
void SvtCTLOptions::SetCTLFontEnabled( sal_Bool _bEnabled )
{
    DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
    pCTLOptions->SetCTLFontEnabled( _bEnabled );
}
// -----------------------------------------------------------------------------
sal_Bool SvtCTLOptions::IsCTLFontEnabled() const
{
    DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
    return pCTLOptions->IsCTLFontEnabled();
}
// -----------------------------------------------------------------------------
void SvtCTLOptions::SetCTLSequenceChecking( sal_Bool _bEnabled )
{
    DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
    pCTLOptions->SetCTLSequenceChecking(_bEnabled);
}
// -----------------------------------------------------------------------------
sal_Bool SvtCTLOptions::IsCTLSequenceChecking() const
{
    DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
    return pCTLOptions->IsCTLSequenceChecking();
}

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

#pragma hdrstop

#ifndef _SVTOOLS_CTLOPTIONS_HXX
#include "ctloptions.hxx"
#endif
#ifndef _UTL_CONFIGITEM_HXX_
#include <unotools/configitem.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_ANY_H_
#include <com/sun/star/uno/Any.h>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

using namespace ::com::sun::star::uno;

#define ASCII_STR(s)    rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(s) )

// SvtCJKOptions_Impl ----------------------------------------------------------

class SvtCTLOptions_Impl : public utl::ConfigItem
{
private:
    static Sequence< rtl::OUString > m_aPropertyNames;

    sal_Bool                        m_bIsLoaded;
    sal_Bool                        m_bCTLFontEnabled;
    sal_Bool                        m_bCTLSequenceChecking;
    SvtCTLOptions::CursorMovement   m_eCTLCursorMovement;
    SvtCTLOptions::TextNumerals     m_eCTLTextNumerals;

public:
    SvtCTLOptions_Impl();
    ~SvtCTLOptions_Impl();

    virtual void    Notify( const Sequence< rtl::OUString >& _aPropertyNames );
    virtual void    Commit();
    void            Load();

    sal_Bool        IsLoaded() { return m_bIsLoaded; }
    void            SetCTLFontEnabled( sal_Bool _bEnabled );
    sal_Bool        IsCTLFontEnabled() const { return m_bCTLFontEnabled; }

    void            SetCTLSequenceChecking( sal_Bool _bEnabled );
    sal_Bool        IsCTLSequenceChecking() const { return m_bCTLSequenceChecking;}

    void            SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement );
    SvtCTLOptions::CursorMovement
                    GetCTLCursorMovement() const { return m_eCTLCursorMovement; }

    void            SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals );
    SvtCTLOptions::TextNumerals
                    GetCTLTextNumerals() const { return m_eCTLTextNumerals; }
};
//------------------------------------------------------------------------------
Sequence< rtl::OUString > SvtCTLOptions_Impl::m_aPropertyNames;
//------------------------------------------------------------------------------
SvtCTLOptions_Impl::SvtCTLOptions_Impl() :

    utl::ConfigItem( ASCII_STR("Office.Common/I18N/CTL") ),

    m_bIsLoaded             ( sal_False ),
    m_bCTLFontEnabled       ( sal_False ),
    m_bCTLSequenceChecking  ( sal_False ),
    m_eCTLCursorMovement    ( SvtCTLOptions::MOVEMENT_LOGICAL ),
    m_eCTLTextNumerals      ( SvtCTLOptions::NUMERALS_ARABIC )

{
}
//------------------------------------------------------------------------------
SvtCTLOptions_Impl::~SvtCTLOptions_Impl()
{
    if ( IsModified() == sal_True )
        Commit();
}
// -----------------------------------------------------------------------------
void SvtCTLOptions_Impl::Notify( const Sequence< rtl::OUString >& aPropertyNames )
{
    Load();
}
// -----------------------------------------------------------------------------
void SvtCTLOptions_Impl::Commit()
{
    rtl::OUString* pNames = m_aPropertyNames.getArray();
    Sequence< Any > aValues( m_aPropertyNames.getLength() );
    Any* pValues = aValues.getArray();
    const Type& rType = ::getBooleanCppuType();
    for ( int nProp = 0; nProp < m_aPropertyNames.getLength(); nProp++ )
    {
        switch ( nProp )
        {
            case  0: pValues[nProp].setValue( &m_bCTLFontEnabled, rType ); break;
            case  1: pValues[nProp].setValue( &m_bCTLSequenceChecking, rType ); break;
            case  2: pValues[nProp] <<= (sal_Int32)m_eCTLCursorMovement; break;
            case  3: pValues[nProp] <<= (sal_Int32)m_eCTLTextNumerals; break;
        }
    }
    PutProperties( m_aPropertyNames, aValues );
}
// -----------------------------------------------------------------------------
void SvtCTLOptions_Impl::Load()
{
    if ( !m_aPropertyNames.getLength() )
    {
        m_aPropertyNames.realloc(4);
        rtl::OUString* pNames = m_aPropertyNames.getArray();
        pNames[0] = ASCII_STR("CTLFont");
        pNames[1] = ASCII_STR("CTLSequenceChecking");
        pNames[2] = ASCII_STR("CTLCursorMovement");
        pNames[3] = ASCII_STR("CTLTextNumerals");
        EnableNotification( m_aPropertyNames );
    }
    Sequence< Any > aValues = GetProperties( m_aPropertyNames );
    const Any* pValues = aValues.getConstArray();
    DBG_ASSERT( aValues.getLength() == m_aPropertyNames.getLength(), "GetProperties failed" );
    if ( aValues.getLength() == m_aPropertyNames.getLength() )
    {
        sal_Bool bValue = sal_False;
        sal_Int32 nValue = 0;

        for ( int nProp = 0; nProp < m_aPropertyNames.getLength(); nProp++ )
        {
            if ( pValues[nProp].hasValue() )
            {
                if ( pValues[nProp] >>= bValue )
                {
                    switch ( nProp )
                    {
                        case 0: m_bCTLFontEnabled = bValue; break;
                        case 1: m_bCTLSequenceChecking = bValue;break;
                    }
                }
                else if ( pValues[nProp] >>= nValue )
                {
                    switch ( nProp )
                    {
                        case 2: m_eCTLCursorMovement = (SvtCTLOptions::CursorMovement)nValue; break;
                        case 3: m_eCTLTextNumerals = (SvtCTLOptions::TextNumerals)nValue;break;
                    }
                }
            }
        }
    }
    m_bIsLoaded = sal_True;
}
//------------------------------------------------------------------------------
void SvtCTLOptions_Impl::SetCTLFontEnabled( sal_Bool _bEnabled )
{
    if(m_bCTLFontEnabled != _bEnabled)
    {
        m_bCTLFontEnabled = _bEnabled;
        SetModified();
    }
}
//------------------------------------------------------------------------------
void SvtCTLOptions_Impl::SetCTLSequenceChecking( sal_Bool _bEnabled )
{
    if(m_bCTLSequenceChecking != _bEnabled)
    {
        SetModified();
        m_bCTLSequenceChecking = _bEnabled;
    }
}
//------------------------------------------------------------------------------
void SvtCTLOptions_Impl::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement )
{
    if ( m_eCTLCursorMovement != _eMovement )
    {
        SetModified();
        m_eCTLCursorMovement = _eMovement;
    }
}
//------------------------------------------------------------------------------
void SvtCTLOptions_Impl::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals )
{
    if ( m_eCTLTextNumerals != _eNumerals )
    {
        SetModified();
        m_eCTLTextNumerals = _eNumerals;
    }
}
// global ----------------------------------------------------------------

static SvtCTLOptions_Impl*  pCTLOptions = NULL;
static sal_Int32            nCTLRefCount = 0;
static ::osl::Mutex         aCTLMutex;

// class SvtCTLOptions --------------------------------------------------

SvtCTLOptions::SvtCTLOptions( sal_Bool bDontLoad )
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( aCTLMutex );
    if ( !pCTLOptions )
        pCTLOptions = new SvtCTLOptions_Impl;
    if( !bDontLoad && !pCTLOptions->IsLoaded() )
        pCTLOptions->Load();

    ++nCTLRefCount;
    m_pImp = pCTLOptions;
}

// -----------------------------------------------------------------------

SvtCTLOptions::~SvtCTLOptions()
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( aCTLMutex );

    if ( !--nCTLRefCount )
        DELETEZ( pCTLOptions );
}
// -----------------------------------------------------------------------------
void SvtCTLOptions::SetCTLFontEnabled( sal_Bool _bEnabled )
{
    DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
    pCTLOptions->SetCTLFontEnabled( _bEnabled );
}
// -----------------------------------------------------------------------------
sal_Bool SvtCTLOptions::IsCTLFontEnabled() const
{
    DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
    return pCTLOptions->IsCTLFontEnabled();
}
// -----------------------------------------------------------------------------
void SvtCTLOptions::SetCTLSequenceChecking( sal_Bool _bEnabled )
{
    DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
    pCTLOptions->SetCTLSequenceChecking(_bEnabled);
}
// -----------------------------------------------------------------------------
sal_Bool SvtCTLOptions::IsCTLSequenceChecking() const
{
    DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
    return pCTLOptions->IsCTLSequenceChecking();
}
// -----------------------------------------------------------------------------
void SvtCTLOptions::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement )
{
    DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
    pCTLOptions->SetCTLCursorMovement( _eMovement );
}
// -----------------------------------------------------------------------------
SvtCTLOptions::CursorMovement SvtCTLOptions::GetCTLCursorMovement() const
{
    DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
    return pCTLOptions->GetCTLCursorMovement();
}
// -----------------------------------------------------------------------------
void SvtCTLOptions::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals )
{
    DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
    pCTLOptions->SetCTLTextNumerals( _eNumerals );
}
// -----------------------------------------------------------------------------
SvtCTLOptions::TextNumerals SvtCTLOptions::GetCTLTextNumerals() const
{
    DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
    return pCTLOptions->GetCTLTextNumerals();
}
<|endoftext|>