<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 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 "Xerces" 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) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.3  2002/03/21 16:31:43  knoaman
 * Remove data/methods from SchemaElementDecl that are not used.
 *
 * Revision 1.2  2002/02/06 22:30:50  knoaman
 * Added a new attribute to store the wild card information for elements of type 'anyType'.
 *
 * Revision 1.1.1.1  2002/02/01 22:22:46  peiyongz
 * sane_include
 *
 * Revision 1.18  2002/01/02 15:20:22  tng
 * Schema Fix: should not store a temp value as the key in the element pool and the attribute pool.
 *
 * Revision 1.17  2001/11/02 14:13:45  knoaman
 * Add support for identity constraints.
 *
 * Revision 1.16  2001/10/11 12:07:39  tng
 * Schema: model type should be based on complextypeinfo if exists.
 *
 * Revision 1.15  2001/09/14 14:50:22  tng
 * Schema: Fix some wildcard bugs, and some retrieving qualified/unqualified element decl problems.
 *
 * Revision 1.14  2001/09/11 13:02:40  tng
 * [Bug 3523] SchemaElementDecl.cpp(242) : error C2202 : not all control paths return a value
 *
 * Revision 1.13  2001/08/29 20:52:35  tng
 * Schema: xsi:type support
 *
 * Revision 1.12  2001/08/21 16:06:11  tng
 * Schema: Unique Particle Attribution Constraint Checking.
 *
 * Revision 1.11  2001/07/24 18:33:46  knoaman
 * Added support for <group> + extra constraint checking for complexType
 *
 * Revision 1.10  2001/07/09 15:22:43  knoaman
 * complete <any> declaration.
 *
 * Revision 1.9  2001/06/13 20:51:18  peiyongz
 * fIsMixed: to handle mixed Content Model
 *
 * Revision 1.8  2001/05/11 13:27:35  tng
 * Copyright update.
 *
 * Revision 1.7  2001/05/03 20:34:42  tng
 * Schema: SchemaValidator update
 *
 * Revision 1.6  2001/05/03 19:17:59  knoaman
 * TraverseSchema Part II.
 *
 * Revision 1.5  2001/04/19 17:43:16  knoaman
 * More schema implementation classes.
 *
 * Revision 1.4  2001/03/21 21:56:33  tng
 * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
 *
 * Revision 1.3  2001/03/21 19:30:15  tng
 * Schema: Content Model Updates, by Pei Yong Zhang.
 *
 * Revision 1.2  2001/03/07 17:42:12  tng
 * fix typo
 *
 * Revision 1.1  2001/02/27 18:48:22  tng
 * Schema: Add SchemaAttDef, SchemaElementDecl, SchemaAttDefList.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/XMLUni.hpp>
#include <xercesc/validators/schema/SchemaAttDefList.hpp>
#include <xercesc/validators/schema/SchemaElementDecl.hpp>
#include <xercesc/validators/schema/identity/IdentityConstraint.hpp>

// ---------------------------------------------------------------------------
//  SchemaElementDecl: Constructors and Destructor
// ---------------------------------------------------------------------------
SchemaElementDecl::SchemaElementDecl() :

    fModelType(Any)
    , fDatatypeValidator(0)
    , fEnclosingScope(Grammar::TOP_LEVEL_SCOPE)
    , fBlockSet(0)
    , fFinalSet(0)
    , fMiscFlags(0)
    , fDefaultValue(0)
    , fSubstitutionGroupName(0)
    , fComplexTypeInfo(0)
    , fXsiComplexTypeInfo(0)
    , fAttDefs(0)
    , fIdentityConstraints(0)
    , fAttWildCard(0)
{
}

SchemaElementDecl::SchemaElementDecl(const XMLCh* const                  prefix
                                   , const XMLCh* const                  localPart
                                   , const int                           uriId
                                   , const SchemaElementDecl::ModelTypes type
                                   , const int                           enclosingScope
                                   ) :
    fModelType(type)
    , fDatatypeValidator(0)
    , fEnclosingScope(enclosingScope)
    , fBlockSet(0)
    , fFinalSet(0)
    , fMiscFlags(0)
    , fDefaultValue(0)
    , fSubstitutionGroupName(0)
    , fComplexTypeInfo(0)
    , fXsiComplexTypeInfo(0)
    , fAttDefs(0)
    , fIdentityConstraints(0)
    , fAttWildCard(0)
{
    setElementName(prefix, localPart, uriId);
}

SchemaElementDecl::SchemaElementDecl(const QName* const                  elementName
                                   , const SchemaElementDecl::ModelTypes type
                                   , const int                           enclosingScope
                                   ) :
    fModelType(type)
    , fDatatypeValidator(0)
    , fEnclosingScope(enclosingScope)
    , fBlockSet(0)
    , fFinalSet(0)
    , fMiscFlags(0)
    , fDefaultValue(0)
    , fSubstitutionGroupName(0)
    , fComplexTypeInfo(0)
    , fXsiComplexTypeInfo(0)
    , fAttDefs(0)
    , fIdentityConstraints(0)
    , fAttWildCard(0)
{
    setElementName(elementName);
}

SchemaElementDecl::~SchemaElementDecl()
{
    delete [] fDefaultValue;
    delete [] fSubstitutionGroupName;
    delete fAttDefs;
    delete fIdentityConstraints;
    delete fAttWildCard;
}

// ---------------------------------------------------------------------------
//  SchemaElementDecl: XMLElementDecl virtual interface implementation
// ---------------------------------------------------------------------------
XMLAttDef* SchemaElementDecl::findAttr(const XMLCh* const    qName
                                     , const unsigned int    uriId
                                     , const XMLCh* const    baseName
                                     , const XMLCh* const    prefix
                                     , const LookupOpts      options
                                     , bool&           wasAdded) const
{
    if (fXsiComplexTypeInfo) {
        return fXsiComplexTypeInfo->findAttr(qName, uriId, baseName, prefix, options, wasAdded);
    }
    else if (fComplexTypeInfo) {
        return fComplexTypeInfo->findAttr(qName, uriId, baseName, prefix, options, wasAdded);
    }
    else {
        if (options == XMLElementDecl::AddIfNotFound) {
            SchemaAttDef* retVal = 0;

            // If no att list exist yet, then create one
            if (!fAttDefs) {
                // Use a hash modulus of 29 and tell it owns its elements
                ((SchemaElementDecl*)this)->fAttDefs = new RefHash2KeysTableOf<SchemaAttDef>(29, true);
            }

            retVal = fAttDefs->get(baseName, uriId);

            // Fault it in if not found and ask to add it
            if (!retVal)
            {
                // And add a default attribute for this name
                retVal = new SchemaAttDef(prefix, baseName, uriId);
                retVal->setElemId(getId());
                fAttDefs->put((void*)retVal->getAttName()->getLocalPart(), uriId, retVal);

                wasAdded = true;
            }
             else
            {
                wasAdded = false;
            }
            return retVal;
        }
        else {
            wasAdded = false;
            return 0;
        }
    }
}

XMLAttDefList& SchemaElementDecl::getAttDefList() const
{
    if (fXsiComplexTypeInfo) {
        return fXsiComplexTypeInfo->getAttDefList();
    }
    else if (fComplexTypeInfo) {
        return fComplexTypeInfo->getAttDefList();
    }
    else {
        ThrowXML(RuntimeException, XMLExcepts::DV_InvalidOperation);
    }

    return *(XMLAttDefList*)0 ;
}

XMLElementDecl::CharDataOpts SchemaElementDecl::getCharDataOpts() const
{
    SchemaElementDecl::ModelTypes modelType = fModelType;

    if (fXsiComplexTypeInfo) {
        modelType = (SchemaElementDecl::ModelTypes) fXsiComplexTypeInfo->getContentType();
    }
    else if (fComplexTypeInfo) {
        modelType = (SchemaElementDecl::ModelTypes) fComplexTypeInfo->getContentType();
    }

    XMLElementDecl::CharDataOpts retVal;
    switch(modelType)
    {
        case Children :
            retVal = XMLElementDecl::SpacesOk;
            break;

        case Empty :
            retVal = XMLElementDecl::NoCharData;
            break;

        default :
            retVal = XMLElementDecl::AllCharData;
            break;
    }
    return retVal;
}

bool SchemaElementDecl::hasAttDefs() const
{
    if (fXsiComplexTypeInfo) {
        return fXsiComplexTypeInfo->hasAttDefs();
    }
    else if (fComplexTypeInfo) {
        return fComplexTypeInfo->hasAttDefs();
    }

    // If the collection hasn't been faulted in, then no att defs
    return false;

}

bool SchemaElementDecl::resetDefs()
{
    if (fXsiComplexTypeInfo) {
        return fXsiComplexTypeInfo->resetDefs();
    }
    else if (fComplexTypeInfo) {
        return fComplexTypeInfo->resetDefs();
    }
    else if (fAttDefs) {
        //all the attdefs here are faulted-in, so just reset the fAttDefs
        //but still return false to indicate there is no real att defs
        // defined in this element
        fAttDefs->removeAll();
    }

    return false;
}

const XMLCh*
SchemaElementDecl::getFormattedContentModel() const
{
    if (fXsiComplexTypeInfo) {
        return fXsiComplexTypeInfo->getFormattedContentModel();
    }
    else if (fComplexTypeInfo) {
        return fComplexTypeInfo->getFormattedContentModel();
    }
    return 0;
}

// ---------------------------------------------------------------------------
//  SchemaElementDecl: Getter methods
// ---------------------------------------------------------------------------
const SchemaAttDef* SchemaElementDecl::getAttDef(const XMLCh* const baseName, const int uriId) const
{
    if (fXsiComplexTypeInfo) {
        return fXsiComplexTypeInfo->getAttDef(baseName, uriId);
    }
    else if (fComplexTypeInfo) {
        return fComplexTypeInfo->getAttDef(baseName, uriId);
    }

    // If no complex type, then return a null
    return 0;

}

SchemaAttDef* SchemaElementDecl::getAttDef(const XMLCh* const baseName, const int uriId)
{
    if (fXsiComplexTypeInfo) {
        return fXsiComplexTypeInfo->getAttDef(baseName, uriId);
    }
    else if (fComplexTypeInfo) {
        return fComplexTypeInfo->getAttDef(baseName, uriId);
    }

    // If no complex type, then return a null
    return 0;
}

<commit_msg>Bug#8898: SchemaElementDecl doesn't compile with Intel C++ for IA32,                   patch from Curt Arnold<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 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 "Xerces" 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) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.4  2002/05/08 13:53:37  peiyongz
 * Bug#8898: SchemaElementDecl doesn't compile with Intel C++ for IA32,
 *                   patch from Curt Arnold
 *
 * Revision 1.3  2002/03/21 16:31:43  knoaman
 * Remove data/methods from SchemaElementDecl that are not used.
 *
 * Revision 1.2  2002/02/06 22:30:50  knoaman
 * Added a new attribute to store the wild card information for elements of type 'anyType'.
 *
 * Revision 1.1.1.1  2002/02/01 22:22:46  peiyongz
 * sane_include
 *
 * Revision 1.18  2002/01/02 15:20:22  tng
 * Schema Fix: should not store a temp value as the key in the element pool and the attribute pool.
 *
 * Revision 1.17  2001/11/02 14:13:45  knoaman
 * Add support for identity constraints.
 *
 * Revision 1.16  2001/10/11 12:07:39  tng
 * Schema: model type should be based on complextypeinfo if exists.
 *
 * Revision 1.15  2001/09/14 14:50:22  tng
 * Schema: Fix some wildcard bugs, and some retrieving qualified/unqualified element decl problems.
 *
 * Revision 1.14  2001/09/11 13:02:40  tng
 * [Bug 3523] SchemaElementDecl.cpp(242) : error C2202 : not all control paths return a value
 *
 * Revision 1.13  2001/08/29 20:52:35  tng
 * Schema: xsi:type support
 *
 * Revision 1.12  2001/08/21 16:06:11  tng
 * Schema: Unique Particle Attribution Constraint Checking.
 *
 * Revision 1.11  2001/07/24 18:33:46  knoaman
 * Added support for <group> + extra constraint checking for complexType
 *
 * Revision 1.10  2001/07/09 15:22:43  knoaman
 * complete <any> declaration.
 *
 * Revision 1.9  2001/06/13 20:51:18  peiyongz
 * fIsMixed: to handle mixed Content Model
 *
 * Revision 1.8  2001/05/11 13:27:35  tng
 * Copyright update.
 *
 * Revision 1.7  2001/05/03 20:34:42  tng
 * Schema: SchemaValidator update
 *
 * Revision 1.6  2001/05/03 19:17:59  knoaman
 * TraverseSchema Part II.
 *
 * Revision 1.5  2001/04/19 17:43:16  knoaman
 * More schema implementation classes.
 *
 * Revision 1.4  2001/03/21 21:56:33  tng
 * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
 *
 * Revision 1.3  2001/03/21 19:30:15  tng
 * Schema: Content Model Updates, by Pei Yong Zhang.
 *
 * Revision 1.2  2001/03/07 17:42:12  tng
 * fix typo
 *
 * Revision 1.1  2001/02/27 18:48:22  tng
 * Schema: Add SchemaAttDef, SchemaElementDecl, SchemaAttDefList.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/XMLUni.hpp>
#include <xercesc/validators/schema/SchemaAttDefList.hpp>
#include <xercesc/validators/schema/SchemaElementDecl.hpp>
#include <xercesc/validators/schema/identity/IdentityConstraint.hpp>

// ---------------------------------------------------------------------------
//  SchemaElementDecl: Constructors and Destructor
// ---------------------------------------------------------------------------
SchemaElementDecl::SchemaElementDecl() :

    fModelType(Any)
    , fDatatypeValidator(0)
    , fEnclosingScope(Grammar::TOP_LEVEL_SCOPE)
    , fBlockSet(0)
    , fFinalSet(0)
    , fMiscFlags(0)
    , fDefaultValue(0)
    , fSubstitutionGroupName(0)
    , fComplexTypeInfo(0)
    , fXsiComplexTypeInfo(0)
    , fAttDefs(0)
    , fIdentityConstraints(0)
    , fAttWildCard(0)
{
}

SchemaElementDecl::SchemaElementDecl(const XMLCh* const                  prefix
                                   , const XMLCh* const                  localPart
                                   , const int                           uriId
                                   , const SchemaElementDecl::ModelTypes type
                                   , const int                           enclosingScope
                                   ) :
    fModelType(type)
    , fDatatypeValidator(0)
    , fEnclosingScope(enclosingScope)
    , fBlockSet(0)
    , fFinalSet(0)
    , fMiscFlags(0)
    , fDefaultValue(0)
    , fSubstitutionGroupName(0)
    , fComplexTypeInfo(0)
    , fXsiComplexTypeInfo(0)
    , fAttDefs(0)
    , fIdentityConstraints(0)
    , fAttWildCard(0)
{
    setElementName(prefix, localPart, uriId);
}

SchemaElementDecl::SchemaElementDecl(const QName* const                  elementName
                                   , const SchemaElementDecl::ModelTypes type
                                   , const int                           enclosingScope
                                   ) :
    fModelType(type)
    , fDatatypeValidator(0)
    , fEnclosingScope(enclosingScope)
    , fBlockSet(0)
    , fFinalSet(0)
    , fMiscFlags(0)
    , fDefaultValue(0)
    , fSubstitutionGroupName(0)
    , fComplexTypeInfo(0)
    , fXsiComplexTypeInfo(0)
    , fAttDefs(0)
    , fIdentityConstraints(0)
    , fAttWildCard(0)
{
    setElementName(elementName);
}

SchemaElementDecl::~SchemaElementDecl()
{
    delete [] fDefaultValue;
    delete [] fSubstitutionGroupName;
    delete fAttDefs;
    delete fIdentityConstraints;
    delete fAttWildCard;
}

// ---------------------------------------------------------------------------
//  SchemaElementDecl: XMLElementDecl virtual interface implementation
// ---------------------------------------------------------------------------
XMLAttDef* SchemaElementDecl::findAttr(const XMLCh* const    qName
                                     , const unsigned int    uriId
                                     , const XMLCh* const    baseName
                                     , const XMLCh* const    prefix
                                     , const LookupOpts      options
                                     , bool&           wasAdded) const
{
    if (fXsiComplexTypeInfo) {
        return fXsiComplexTypeInfo->findAttr(qName, uriId, baseName, prefix, options, wasAdded);
    }
    else if (fComplexTypeInfo) {
        return fComplexTypeInfo->findAttr(qName, uriId, baseName, prefix, options, wasAdded);
    }
    else {
        if (options == XMLElementDecl::AddIfNotFound) {
            SchemaAttDef* retVal = 0;

            // If no att list exist yet, then create one
            if (!fAttDefs) {
                // Use a hash modulus of 29 and tell it owns its elements
                ((SchemaElementDecl*)this)->fAttDefs = new RefHash2KeysTableOf<SchemaAttDef>(29, true);
            }

            retVal = fAttDefs->get(baseName, uriId);

            // Fault it in if not found and ask to add it
            if (!retVal)
            {
                // And add a default attribute for this name
                retVal = new SchemaAttDef(prefix, baseName, uriId);
                retVal->setElemId(getId());
                fAttDefs->put((void*)retVal->getAttName()->getLocalPart(), uriId, retVal);

                wasAdded = true;
            }
             else
            {
                wasAdded = false;
            }
            return retVal;
        }
        else {
            wasAdded = false;
            return 0;
        }
    }
}

XMLAttDefList& SchemaElementDecl::getAttDefList() const
{
    if (fXsiComplexTypeInfo) {
        return fXsiComplexTypeInfo->getAttDefList();
    }
    else if (!fComplexTypeInfo)
	{
        ThrowXML(RuntimeException, XMLExcepts::DV_InvalidOperation);
    }

	return fComplexTypeInfo->getAttDefList();
}

XMLElementDecl::CharDataOpts SchemaElementDecl::getCharDataOpts() const
{
    SchemaElementDecl::ModelTypes modelType = fModelType;

    if (fXsiComplexTypeInfo) {
        modelType = (SchemaElementDecl::ModelTypes) fXsiComplexTypeInfo->getContentType();
    }
    else if (fComplexTypeInfo) {
        modelType = (SchemaElementDecl::ModelTypes) fComplexTypeInfo->getContentType();
    }

    XMLElementDecl::CharDataOpts retVal;
    switch(modelType)
    {
        case Children :
            retVal = XMLElementDecl::SpacesOk;
            break;

        case Empty :
            retVal = XMLElementDecl::NoCharData;
            break;

        default :
            retVal = XMLElementDecl::AllCharData;
            break;
    }
    return retVal;
}

bool SchemaElementDecl::hasAttDefs() const
{
    if (fXsiComplexTypeInfo) {
        return fXsiComplexTypeInfo->hasAttDefs();
    }
    else if (fComplexTypeInfo) {
        return fComplexTypeInfo->hasAttDefs();
    }

    // If the collection hasn't been faulted in, then no att defs
    return false;

}

bool SchemaElementDecl::resetDefs()
{
    if (fXsiComplexTypeInfo) {
        return fXsiComplexTypeInfo->resetDefs();
    }
    else if (fComplexTypeInfo) {
        return fComplexTypeInfo->resetDefs();
    }
    else if (fAttDefs) {
        //all the attdefs here are faulted-in, so just reset the fAttDefs
        //but still return false to indicate there is no real att defs
        // defined in this element
        fAttDefs->removeAll();
    }

    return false;
}

const XMLCh*
SchemaElementDecl::getFormattedContentModel() const
{
    if (fXsiComplexTypeInfo) {
        return fXsiComplexTypeInfo->getFormattedContentModel();
    }
    else if (fComplexTypeInfo) {
        return fComplexTypeInfo->getFormattedContentModel();
    }
    return 0;
}

// ---------------------------------------------------------------------------
//  SchemaElementDecl: Getter methods
// ---------------------------------------------------------------------------
const SchemaAttDef* SchemaElementDecl::getAttDef(const XMLCh* const baseName, const int uriId) const
{
    if (fXsiComplexTypeInfo) {
        return fXsiComplexTypeInfo->getAttDef(baseName, uriId);
    }
    else if (fComplexTypeInfo) {
        return fComplexTypeInfo->getAttDef(baseName, uriId);
    }

    // If no complex type, then return a null
    return 0;

}

SchemaAttDef* SchemaElementDecl::getAttDef(const XMLCh* const baseName, const int uriId)
{
    if (fXsiComplexTypeInfo) {
        return fXsiComplexTypeInfo->getAttDef(baseName, uriId);
    }
    else if (fComplexTypeInfo) {
        return fComplexTypeInfo->getAttDef(baseName, uriId);
    }

    // If no complex type, then return a null
    return 0;
}

<|endoftext|>


<commit_before>// This file generated by staff_codegen
// For more information please visit: http://code.google.com/p/staff/
// DO NOT EDIT

#ifneq($(Interface.Classes.$Count),0)
#include <staff/utils/SharedPtr.h>
#ifeqend
#include <staff/utils/Log.h>
#include <staff/utils/fromstring.h>
#include <staff/utils/tostring.h>
#include <staff/utils/HexBinary.h>
#include <staff/utils/Base64Binary.h>
#include <staff/common/Attribute.h>
#include <staff/common/Exception.h>
#include <staff/common/DataObject.h>
#ifneq($(Interface.Classes.$Count),0)
#include <staff/common/Operation.h>
#include <staff/common/IService.h>
#include <staff/component/ServiceInstanceManager.h>
#include <staff/component/Component.h>
#include "$(Interface.FilePath)$(Interface.Name)Impl.h"
#ifeqend // #ifneq($(Interface.Classes.$Count),0)
\
#foreach $(Interface.Structs) // headers for extern abstract types
#ifeq($(Struct.Extern),false)
#ifeq($(Struct.Options.*abstract),true||1)
#var sThisStructNsName $(Struct.NsName)
#var sThisInterfaceNsName $(Interface.NsName)
#var bThisInterfaceIncluded 0
#foreach $(Project.Interfaces)
#foreach $(Interface.Structs)
#ifeq($(Struct.ParentNsName)-$(Struct.Extern),$($sThisStructNsName)-false)
#ifneq($(Interface.NsName),$($sThisInterfaceNsName))
#ifeq($($bThisInterfaceIncluded),0)
#include "$(Interface.FilePath)$(Interface.Name)Wrapper.h"
#var bThisInterfaceIncluded 1
#ifeqend
#ifeqend
#ifeqend
#end
#end
#ifeqend
#ifeqend
#end
\
#include "$(Interface.FilePath)$(Interface.Name)Wrapper.h"

#cginclude <common/Serialization.cpp>

#ifneq($(Interface.Classes.$Count),0)
#foreach $(Interface.Classes)

$(Class.OpeningNs)

$(Class.Name)Wrapper::$(Class.Name)Wrapper(staff::Component* pComponent):
  m_pComponent(pComponent)
{
}

$(Class.Name)Wrapper::~$(Class.Name)Wrapper()
{
}

void $(Class.Name)Wrapper::Invoke(staff::Operation& rOperation, const std::string& sSessionId, const std::string& sInstanceId)
{
  const staff::DataObject& rRequest = rOperation.Request();
  const std::string& sOperationName = rOperation.GetName();

  if (sOperationName == "GetServiceDescription")
  {
    rOperation.SetResponse(GetServiceDescription());
  }
  else
  if (sOperationName == "CreateInstance")
  {
    staff::ServiceInstanceManager::Inst().CreateServiceInstance(sSessionId, m_sName,
                                                                rRequest.GetChildTextByLocalName("sInstanceId"));
  }
  else
  if (sOperationName == "FreeInstance")
  {
    staff::ServiceInstanceManager::Inst().FreeServiceInstance(sSessionId, m_sName,
                                                              rRequest.GetChildTextByLocalName("sInstanceId"));
  }
  else
  {
    staff::SharedPtr<$(Class.Name)Impl> tpServiceImpl = GetImpl(sSessionId, sInstanceId);
#foreach $(Class.Members)
    if (sOperationName == "$(Member.Options.*requestElement||Member.Name)")
    {
#ifneq($(Member.Return.Type)-$(Member.Options.*useParentElement),dataobject-true||dataobject-1)
#ifneq($(Member.Options.*responseElement),)
      rOperation.SetResponseName("$(Member.Options.*responseElement)");
#else
#ifneq($(Member.Return.ResponseName),)
      rOperation.SetResponseName("$(Member.Return.ResponseName)");
#ifeqend
#ifeqend
#ifeqend
\
#ifneq($(Member.Options.*resultElement),)
      rOperation.SetResultName("$(Member.Options.*resultElement)");
#ifeqend
#foreach $(Member.Params)
#ifeq($(Param.DataType.Type),struct||typedef||template||generic||enum)
#ifneq($(Param.DataType.Name),Operation||MessageContext)
      $(Param.DataType.NsName) $(Param.Name)\
#ifeq($(Param.DataType.Type),generic)
 = 0\
#ifeqend
;
#ifeqend
#ifeqend
#end
\
#foreach $(Member.Params)  // ------------------- params ------------------------
#ifeq($(Param.Options.*useParentElement),)
#var sElementName
#else
#var sElementName $(Param.Options.*elementName||Param.Name)
#ifeqend
#ifeq($(Param.DataType.Type),struct||typedef||template||generic||enum)
#context $(Param.DataType)
#indent +2
#ifneq($(Param.Options.*useParentElement||Member.Options.*inlineRequestElement),)
#var sParam $(Param.Name)
#var sParamName
#var sdoParam rRequest
#else
#var sParam $(Param.Name)
#var sParamName $(Param.Name)
#ifeq($(Param.DataType.Type),template) // iterate under parameter, not parameters
#var sdoParam rRequest.GetChildByLocalName("$(Param.Name)")
#else
#var sdoParam rRequest
#ifeqend
#ifeqend
\
#cginclude <common/TypeDeserialization.cpp>
#indent -2
#contextend
#ifeqend
#end       // ----------------- return -------------------
      \
#ifneq($(Member.Return.Name),void)      // !!not_void!!
#ifeq($(Member.Return.Type),struct||typedef||template||enum)
const $(Member.Return.NsName)& tResult = \
#else
#ifeq($(Member.Return.Type),enum)
$(Member.Return.NsName) tResult = \
#else
#ifeq($(Member.Return.Type),generic||string)    // !!generic!!
rOperation.Result().SetValue(\
#else
#ifeq($(Member.Return.Type),dataobject) // !!dataobject!!
#ifeq($(Member.Options.*useParentElement),true||1)
rOperation.Result() = \
#else
rOperation.Result().AppendChild(\
#ifeqend
#ifeqend
#ifeqend
#ifeqend
#ifeqend
#ifeqend // invoke an function
\
tpServiceImpl->$(Member.Name)(\
#foreach $(Member.Params)
#ifeq($(Param.Options.*useParentElement),)
#var sElementName
#else
#var sElementName $(Param.Options.*elementName||Param.Name)
#ifeqend
#ifneq($(Param.$Num),0) // param splitter
, \
#ifeqend // params
#ifeq($(Param.DataType.Name),MessageContext)
rOperation.GetMessageContext()\
#else
#ifeq($(Param.DataType.Name),Operation)
rOperation\
#else
#ifeq($(Param.DataType.Type),string||dataobject)
#context $(Param.DataType)
#ifneq($(Param.Options.*useParentElement||Member.Options.*inlineRequestElement),)
#var sParam $(Param.Name)
#var sParamName
#var sdoParam rRequest
#else
#var sParam
#var sParamName $(Param.Name)
#var sdoParam rRequest
#ifeqend
#cginclude <common/TypeDeserialization.cpp>
#contextend
#else
#ifeq($(Param.DataType.Type),struct||typedef||template||generic||enum)
$(Param.Name)\
#else
#cgerror "Param.DataType.Type = $(Param.DataType.Type);"
#ifeqend
#ifeqend
#ifeqend
#ifeqend
#end // end of function param list
\
#ifneq($(Member.Return.Name),void)
#ifeq($(Member.Return.Type),generic||string)
)\
#else
#ifeq($(Member.Return.Type),dataobject)
#ifneq($(Member.Options.*useParentElement),true||1)
)\
#ifeqend
#ifeqend
#ifeqend
#ifeqend
);
\
\
#ifneq($(Member.Return.Type),generic||string||dataobject)
#context $(Member.Return)
#indent +2
#var sParam tResult
#var sdoParam rOperation.Result()
#cginclude <common/TypeSerialization.cpp>
#indent -2
#contextend
#ifeqend
#ifeq($(Member.Return.Type)-$(Member.Options.*useParentElement),dataobject-true||dataobject-1)
#ifneq($(Member.Options.*responseElement),)
      rOperation.SetResponseName("$(Member.Options.*responseElement)");
#else
#ifneq($(Member.Return.ResponseName),)
      rOperation.SetResponseName("$(Member.Return.ResponseName)");
#ifeqend
#ifeqend
#ifeqend
#ifeq($(Member.Options.*dontSetResultNamespace),true)
      return;
#else
#ifneq($(Member.Options.*responseTargetNamespace),)
#ifneq($(Class.Options.*targetNamespacePrefix),)
      rOperation.GetResponse().SetNamespace("$(Member.Options.*responseTargetNamespace)", "$(Class.Options.*targetNamespacePrefix)");
#else
      rOperation.GetResponse().SetNamespaceUriGenPrefix("$(Member.Options.*responseTargetNamespace)");
#ifeqend
      return;
#else
#ifeq($(Member.Options.*mep),in-only)
      return;
#ifeqend
#ifeqend
#ifeqend
    }
    else
#end
    {
      STAFF_THROW(staff::RemoteException, "Unknown Operation: " + rOperation.GetName());
    }

#ifneq($(Class.Options.*targetNamespacePrefix),)
#ifneq($(Class.Options.*targetNamespace),)
    rOperation.GetResponse().SetNamespace("$(Class.Options.*targetNamespace)", "$(Class.Options.*targetNamespacePrefix)");
#else
    rOperation.GetResponse().SetNamespace("http://tempui.org/" + m_pComponent->GetName(), "$(Class.Options.*targetNamespacePrefix)");
#ifeqend
#else
    rOperation.GetResponse().SetNamespaceUriGenPrefix("$(Class.Options.*targetNamespace||Interface.Options.*targetNamespace||"http://tempui.org/$(Class.ServiceNsName)")");
#ifeqend
  }
}

const std::string& $(Class.Name)Wrapper::GetName() const
{
  return m_sName;
}

const std::string& $(Class.Name)Wrapper::GetDescr() const
{
  return m_sDescr;
}

const staff::Component* $(Class.Name)Wrapper::GetComponent() const
{
  return m_pComponent;
}

staff::Component* $(Class.Name)Wrapper::GetComponent()
{
  return m_pComponent;
}

staff::PIService& $(Class.Name)Wrapper::GetImpl(const std::string& sSessionId, const std::string& sInstanceId)
{
  return staff::ServiceInstanceManager::Inst().GetServiceInstance(sSessionId, m_sName, sInstanceId);
}

staff::PIService $(Class.Name)Wrapper::NewImpl()
{
  return new $(Class.Name)Impl;
}

bool $(Class.Name)Wrapper::IsLoadAtStartup() const
{
  return \
#ifeq($(Class.Options.*loadAtStartup),true)
true;
#else
false;
#ifeqend
}

std::string $(Class.Name)Wrapper::GetDependencies() const
{
  return "$(Class.Options.*dependencies)";
}

staff::DataObject $(Class.Name)Wrapper::GetOperations() const
{
  staff::DataObject tOperations("Operations");

#foreach $(Class.Members)
  {// Operation: $(Member.Return.NsName) $(Member.Name)($(Member.Params))$(Member.Const)
    staff::DataObject tOp$(Member.Name) = tOperations.CreateChild("Operation");
    tOp$(Member.Name).CreateChild("Name", "$(Member.Name)");
    tOp$(Member.Name).CreateChild("RestMethod", "$(Member.Options.*restMethod)");
    tOp$(Member.Name).CreateChild("RestLocation", "$(Member.Options.*restLocation)");
  }
#end

  return tOperations;
}

staff::DataObject $(Class.Name)Wrapper::GetServiceDescription() const
{
  staff::DataObject tServiceDescription;

  tServiceDescription.Create("ServiceDescription");
  tServiceDescription.DeclareDefaultNamespace("http://tempui.org/staff/service-description");

  tServiceDescription.CreateChild("Name", m_sName);
  tServiceDescription.CreateChild("Description", m_sDescr);

  tServiceDescription.AppendChild(GetOperations());

  return tServiceDescription;
}

const std::string $(Class.Name)Wrapper::m_sName = "$(Class.ServiceNsName)";
const std::string $(Class.Name)Wrapper::m_sDescr = \
#ifneq($(Class.Description),)
"$(Class.Description)";
#else
"Staff service $(Class.ServiceName)";
#ifeqend

$(Class.EndingNs)
#end
#ifeqend // #ifneq($(Interface.Classes.$Count),0)

<commit_msg>codegen: Fixed deserializing of non-container template parameters in wrapper<commit_after>// This file generated by staff_codegen
// For more information please visit: http://code.google.com/p/staff/
// DO NOT EDIT

#ifneq($(Interface.Classes.$Count),0)
#include <staff/utils/SharedPtr.h>
#ifeqend
#include <staff/utils/Log.h>
#include <staff/utils/fromstring.h>
#include <staff/utils/tostring.h>
#include <staff/utils/HexBinary.h>
#include <staff/utils/Base64Binary.h>
#include <staff/common/Attribute.h>
#include <staff/common/Exception.h>
#include <staff/common/DataObject.h>
#ifneq($(Interface.Classes.$Count),0)
#include <staff/common/Operation.h>
#include <staff/common/IService.h>
#include <staff/component/ServiceInstanceManager.h>
#include <staff/component/Component.h>
#include "$(Interface.FilePath)$(Interface.Name)Impl.h"
#ifeqend // #ifneq($(Interface.Classes.$Count),0)
\
#foreach $(Interface.Structs) // headers for extern abstract types
#ifeq($(Struct.Extern),false)
#ifeq($(Struct.Options.*abstract),true||1)
#var sThisStructNsName $(Struct.NsName)
#var sThisInterfaceNsName $(Interface.NsName)
#var bThisInterfaceIncluded 0
#foreach $(Project.Interfaces)
#foreach $(Interface.Structs)
#ifeq($(Struct.ParentNsName)-$(Struct.Extern),$($sThisStructNsName)-false)
#ifneq($(Interface.NsName),$($sThisInterfaceNsName))
#ifeq($($bThisInterfaceIncluded),0)
#include "$(Interface.FilePath)$(Interface.Name)Wrapper.h"
#var bThisInterfaceIncluded 1
#ifeqend
#ifeqend
#ifeqend
#end
#end
#ifeqend
#ifeqend
#end
\
#include "$(Interface.FilePath)$(Interface.Name)Wrapper.h"

#cginclude <common/Serialization.cpp>

#ifneq($(Interface.Classes.$Count),0)
#foreach $(Interface.Classes)

$(Class.OpeningNs)

$(Class.Name)Wrapper::$(Class.Name)Wrapper(staff::Component* pComponent):
  m_pComponent(pComponent)
{
}

$(Class.Name)Wrapper::~$(Class.Name)Wrapper()
{
}

void $(Class.Name)Wrapper::Invoke(staff::Operation& rOperation, const std::string& sSessionId, const std::string& sInstanceId)
{
  const staff::DataObject& rRequest = rOperation.Request();
  const std::string& sOperationName = rOperation.GetName();

  if (sOperationName == "GetServiceDescription")
  {
    rOperation.SetResponse(GetServiceDescription());
  }
  else
  if (sOperationName == "CreateInstance")
  {
    staff::ServiceInstanceManager::Inst().CreateServiceInstance(sSessionId, m_sName,
                                                                rRequest.GetChildTextByLocalName("sInstanceId"));
  }
  else
  if (sOperationName == "FreeInstance")
  {
    staff::ServiceInstanceManager::Inst().FreeServiceInstance(sSessionId, m_sName,
                                                              rRequest.GetChildTextByLocalName("sInstanceId"));
  }
  else
  {
    staff::SharedPtr<$(Class.Name)Impl> tpServiceImpl = GetImpl(sSessionId, sInstanceId);
#foreach $(Class.Members)
    if (sOperationName == "$(Member.Options.*requestElement||Member.Name)")
    {
#ifneq($(Member.Return.Type)-$(Member.Options.*useParentElement),dataobject-true||dataobject-1)
#ifneq($(Member.Options.*responseElement),)
      rOperation.SetResponseName("$(Member.Options.*responseElement)");
#else
#ifneq($(Member.Return.ResponseName),)
      rOperation.SetResponseName("$(Member.Return.ResponseName)");
#ifeqend
#ifeqend
#ifeqend
\
#ifneq($(Member.Options.*resultElement),)
      rOperation.SetResultName("$(Member.Options.*resultElement)");
#ifeqend
#foreach $(Member.Params)
#ifeq($(Param.DataType.Type),struct||typedef||template||generic||enum)
#ifneq($(Param.DataType.Name),Operation||MessageContext)
      $(Param.DataType.NsName) $(Param.Name)\
#ifeq($(Param.DataType.Type),generic)
 = 0\
#ifeqend
;
#ifeqend
#ifeqend
#end
\
#foreach $(Member.Params)  // ------------------- params ------------------------
#ifeq($(Param.Options.*useParentElement),)
#var sElementName
#else
#var sElementName $(Param.Options.*elementName||Param.Name)
#ifeqend
#ifeq($(Param.DataType.Type),struct||typedef||template||generic||enum)
#context $(Param.DataType)
#indent +2
#ifneq($(Param.Options.*useParentElement||Member.Options.*inlineRequestElement),)
#var sParam $(Param.Name)
#var sParamName
#var sdoParam rRequest
#else
#var sParam $(Param.Name)
#var sParamName $(Param.Name)
#ifeq($(Param.DataType.Type),template) // iterate under parameter, not parameters
#ifeq($(Param.DataType.Name),list||vector||map||Array) // only for containers
#var sdoParam rRequest.GetChildByLocalName("$(Param.Name)")
#else
#var sdoParam rRequest
#ifeqend
#else
#var sdoParam rRequest
#ifeqend
#ifeqend
\
#cginclude <common/TypeDeserialization.cpp>
#indent -2
#contextend
#ifeqend
#end       // ----------------- return -------------------
      \
#ifneq($(Member.Return.Name),void)      // !!not_void!!
#ifeq($(Member.Return.Type),struct||typedef||template||enum)
const $(Member.Return.NsName)& tResult = \
#else
#ifeq($(Member.Return.Type),enum)
$(Member.Return.NsName) tResult = \
#else
#ifeq($(Member.Return.Type),generic||string)    // !!generic!!
rOperation.Result().SetValue(\
#else
#ifeq($(Member.Return.Type),dataobject) // !!dataobject!!
#ifeq($(Member.Options.*useParentElement),true||1)
rOperation.Result() = \
#else
rOperation.Result().AppendChild(\
#ifeqend
#ifeqend
#ifeqend
#ifeqend
#ifeqend
#ifeqend // invoke an function
\
tpServiceImpl->$(Member.Name)(\
#foreach $(Member.Params)
#ifeq($(Param.Options.*useParentElement),)
#var sElementName
#else
#var sElementName $(Param.Options.*elementName||Param.Name)
#ifeqend
#ifneq($(Param.$Num),0) // param splitter
, \
#ifeqend // params
#ifeq($(Param.DataType.Name),MessageContext)
rOperation.GetMessageContext()\
#else
#ifeq($(Param.DataType.Name),Operation)
rOperation\
#else
#ifeq($(Param.DataType.Type),string||dataobject)
#context $(Param.DataType)
#ifneq($(Param.Options.*useParentElement||Member.Options.*inlineRequestElement),)
#var sParam $(Param.Name)
#var sParamName
#var sdoParam rRequest
#else
#var sParam
#var sParamName $(Param.Name)
#var sdoParam rRequest
#ifeqend
#cginclude <common/TypeDeserialization.cpp>
#contextend
#else
#ifeq($(Param.DataType.Type),struct||typedef||template||generic||enum)
$(Param.Name)\
#else
#cgerror "Param.DataType.Type = $(Param.DataType.Type);"
#ifeqend
#ifeqend
#ifeqend
#ifeqend
#end // end of function param list
\
#ifneq($(Member.Return.Name),void)
#ifeq($(Member.Return.Type),generic||string)
)\
#else
#ifeq($(Member.Return.Type),dataobject)
#ifneq($(Member.Options.*useParentElement),true||1)
)\
#ifeqend
#ifeqend
#ifeqend
#ifeqend
);
\
\
#ifneq($(Member.Return.Type),generic||string||dataobject)
#context $(Member.Return)
#indent +2
#var sParam tResult
#var sdoParam rOperation.Result()
#cginclude <common/TypeSerialization.cpp>
#indent -2
#contextend
#ifeqend
#ifeq($(Member.Return.Type)-$(Member.Options.*useParentElement),dataobject-true||dataobject-1)
#ifneq($(Member.Options.*responseElement),)
      rOperation.SetResponseName("$(Member.Options.*responseElement)");
#else
#ifneq($(Member.Return.ResponseName),)
      rOperation.SetResponseName("$(Member.Return.ResponseName)");
#ifeqend
#ifeqend
#ifeqend
#ifeq($(Member.Options.*dontSetResultNamespace),true)
      return;
#else
#ifneq($(Member.Options.*responseTargetNamespace),)
#ifneq($(Class.Options.*targetNamespacePrefix),)
      rOperation.GetResponse().SetNamespace("$(Member.Options.*responseTargetNamespace)", "$(Class.Options.*targetNamespacePrefix)");
#else
      rOperation.GetResponse().SetNamespaceUriGenPrefix("$(Member.Options.*responseTargetNamespace)");
#ifeqend
      return;
#else
#ifeq($(Member.Options.*mep),in-only)
      return;
#ifeqend
#ifeqend
#ifeqend
    }
    else
#end
    {
      STAFF_THROW(staff::RemoteException, "Unknown Operation: " + rOperation.GetName());
    }

#ifneq($(Class.Options.*targetNamespacePrefix),)
#ifneq($(Class.Options.*targetNamespace),)
    rOperation.GetResponse().SetNamespace("$(Class.Options.*targetNamespace)", "$(Class.Options.*targetNamespacePrefix)");
#else
    rOperation.GetResponse().SetNamespace("http://tempui.org/" + m_pComponent->GetName(), "$(Class.Options.*targetNamespacePrefix)");
#ifeqend
#else
    rOperation.GetResponse().SetNamespaceUriGenPrefix("$(Class.Options.*targetNamespace||Interface.Options.*targetNamespace||"http://tempui.org/$(Class.ServiceNsName)")");
#ifeqend
  }
}

const std::string& $(Class.Name)Wrapper::GetName() const
{
  return m_sName;
}

const std::string& $(Class.Name)Wrapper::GetDescr() const
{
  return m_sDescr;
}

const staff::Component* $(Class.Name)Wrapper::GetComponent() const
{
  return m_pComponent;
}

staff::Component* $(Class.Name)Wrapper::GetComponent()
{
  return m_pComponent;
}

staff::PIService& $(Class.Name)Wrapper::GetImpl(const std::string& sSessionId, const std::string& sInstanceId)
{
  return staff::ServiceInstanceManager::Inst().GetServiceInstance(sSessionId, m_sName, sInstanceId);
}

staff::PIService $(Class.Name)Wrapper::NewImpl()
{
  return new $(Class.Name)Impl;
}

bool $(Class.Name)Wrapper::IsLoadAtStartup() const
{
  return \
#ifeq($(Class.Options.*loadAtStartup),true)
true;
#else
false;
#ifeqend
}

std::string $(Class.Name)Wrapper::GetDependencies() const
{
  return "$(Class.Options.*dependencies)";
}

staff::DataObject $(Class.Name)Wrapper::GetOperations() const
{
  staff::DataObject tOperations("Operations");

#foreach $(Class.Members)
  {// Operation: $(Member.Return.NsName) $(Member.Name)($(Member.Params))$(Member.Const)
    staff::DataObject tOp$(Member.Name) = tOperations.CreateChild("Operation");
    tOp$(Member.Name).CreateChild("Name", "$(Member.Name)");
    tOp$(Member.Name).CreateChild("RestMethod", "$(Member.Options.*restMethod)");
    tOp$(Member.Name).CreateChild("RestLocation", "$(Member.Options.*restLocation)");
  }
#end

  return tOperations;
}

staff::DataObject $(Class.Name)Wrapper::GetServiceDescription() const
{
  staff::DataObject tServiceDescription;

  tServiceDescription.Create("ServiceDescription");
  tServiceDescription.DeclareDefaultNamespace("http://tempui.org/staff/service-description");

  tServiceDescription.CreateChild("Name", m_sName);
  tServiceDescription.CreateChild("Description", m_sDescr);

  tServiceDescription.AppendChild(GetOperations());

  return tServiceDescription;
}

const std::string $(Class.Name)Wrapper::m_sName = "$(Class.ServiceNsName)";
const std::string $(Class.Name)Wrapper::m_sDescr = \
#ifneq($(Class.Description),)
"$(Class.Description)";
#else
"Staff service $(Class.ServiceName)";
#ifeqend

$(Class.EndingNs)
#end
#ifeqend // #ifneq($(Interface.Classes.$Count),0)

<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"

#include "gtest/gtest.h"
#include "webrtc/system_wrappers/interface/sleep.h"
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/system_wrappers/source/unittest_utilities.h"

namespace webrtc {

namespace {

const bool kLogTrace = false;  // Set to true to enable debug logging to stdout.

// Cause a process switch. Needed to avoid depending on
// busy-wait in tests.
static void SwitchProcess() {
  // Note - sched_yield has been tried as process switch. This does
  // not cause a process switch enough of the time for reliability.
  SleepMs(1);
}

class ProtectedCount {
public:
  explicit ProtectedCount(CriticalSectionWrapper* crit_sect)
    : crit_sect_(crit_sect),
      count_(0) {
  }

  void Increment() {
    CriticalSectionScoped cs(crit_sect_);
    ++count_;
  }

  int Count() const {
    CriticalSectionScoped cs(crit_sect_);
    return count_;
  }

private:
  CriticalSectionWrapper* crit_sect_;
  int count_;
};

class CritSectTest : public ::testing::Test {
public:
  CritSectTest() : trace_(kLogTrace) {
  }

  // Waits a number of cycles for the count to reach a given value.
  // Returns true if the target is reached or passed.
  bool WaitForCount(int target, ProtectedCount* count) {
    int loop_counter = 0;
    // On Posix, this SwitchProcess() needs to be in a loop to make the
    // test both fast and non-flaky.
    // With 1 us wait as the switch, up to 7 rounds have been observed.
    while (count->Count() < target && loop_counter < 100 * target) {
      ++loop_counter;
      SwitchProcess();
    }
    return (count->Count() >= target);
  }

private:
  ScopedTracing trace_;
};

bool LockUnlockThenStopRunFunction(void* obj) {
  ProtectedCount* the_count = static_cast<ProtectedCount*>(obj);
  the_count->Increment();
  return false;
}

TEST_F(CritSectTest, ThreadWakesOnce) {
  CriticalSectionWrapper* crit_sect =
      CriticalSectionWrapper::CreateCriticalSection();
  ProtectedCount count(crit_sect);
  ThreadWrapper* thread = ThreadWrapper::CreateThread(
      &LockUnlockThenStopRunFunction, &count);
  unsigned int id = 42;
  crit_sect->Enter();
  ASSERT_TRUE(thread->Start(id));
  SwitchProcess();
  // The critical section is of reentrant mode, so this should not release
  // the lock, even though count.Count() locks and unlocks the critical section
  // again.
  // Thus, the thread should not be able to increment the count
  ASSERT_EQ(0, count.Count());
  crit_sect->Leave();  // This frees the thread to act.
  EXPECT_TRUE(WaitForCount(1, &count));
  EXPECT_TRUE(thread->Stop());
  delete thread;
  delete crit_sect;
}

bool LockUnlockRunFunction(void* obj) {
  ProtectedCount* the_count = static_cast<ProtectedCount*>(obj);
  the_count->Increment();
  SwitchProcess();
  return true;
}

TEST_F(CritSectTest, ThreadWakesTwice) {
  CriticalSectionWrapper* crit_sect =
      CriticalSectionWrapper::CreateCriticalSection();
  ProtectedCount count(crit_sect);
  ThreadWrapper* thread = ThreadWrapper::CreateThread(&LockUnlockRunFunction,
                                                      &count);
  unsigned int id = 42;
  crit_sect->Enter();  // Make sure counter stays 0 until we wait for it.
  ASSERT_TRUE(thread->Start(id));
  crit_sect->Leave();

  // The thread is capable of grabbing the lock multiple times,
  // incrementing counter once each time.
  // It's possible for the count to be incremented by more than 2.
  EXPECT_TRUE(WaitForCount(2, &count));
  EXPECT_LE(2, count.Count());

  // The thread does not increment while lock is held.
  crit_sect->Enter();
  int count_before = count.Count();
  for (int i = 0; i < 10; i++) {
    SwitchProcess();
  }
  EXPECT_EQ(count_before, count.Count());
  crit_sect->Leave();

  thread->SetNotAlive();  // Tell thread to exit once run function finishes.
  SwitchProcess();
  EXPECT_LT(count_before, count.Count());
  EXPECT_TRUE(thread->Stop());
  delete thread;
  delete crit_sect;
}

}  // anonymous namespace

}  // namespace webrtc
<commit_msg>Fixing the flakiness of ThreadWakesTwice.<commit_after>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"

#include "gtest/gtest.h"
#include "webrtc/system_wrappers/interface/sleep.h"
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/system_wrappers/source/unittest_utilities.h"

namespace webrtc {

namespace {

const bool kLogTrace = false;  // Set to true to enable debug logging to stdout.

// Cause a process switch. Needed to avoid depending on
// busy-wait in tests.
static void SwitchProcess() {
  // Note - sched_yield has been tried as process switch. This does
  // not cause a process switch enough of the time for reliability.
  SleepMs(1);
}

class ProtectedCount {
public:
  explicit ProtectedCount(CriticalSectionWrapper* crit_sect)
    : crit_sect_(crit_sect),
      count_(0) {
  }

  void Increment() {
    CriticalSectionScoped cs(crit_sect_);
    ++count_;
  }

  int Count() const {
    CriticalSectionScoped cs(crit_sect_);
    return count_;
  }

private:
  CriticalSectionWrapper* crit_sect_;
  int count_;
};

class CritSectTest : public ::testing::Test {
public:
  CritSectTest() : trace_(kLogTrace) {
  }

  // Waits a number of cycles for the count to reach a given value.
  // Returns true if the target is reached or passed.
  bool WaitForCount(int target, ProtectedCount* count) {
    int loop_counter = 0;
    // On Posix, this SwitchProcess() needs to be in a loop to make the
    // test both fast and non-flaky.
    // With 1 us wait as the switch, up to 7 rounds have been observed.
    while (count->Count() < target && loop_counter < 100 * target) {
      ++loop_counter;
      SwitchProcess();
    }
    return (count->Count() >= target);
  }

private:
  ScopedTracing trace_;
};

bool LockUnlockThenStopRunFunction(void* obj) {
  ProtectedCount* the_count = static_cast<ProtectedCount*>(obj);
  the_count->Increment();
  return false;
}

TEST_F(CritSectTest, ThreadWakesOnce) {
  CriticalSectionWrapper* crit_sect =
      CriticalSectionWrapper::CreateCriticalSection();
  ProtectedCount count(crit_sect);
  ThreadWrapper* thread = ThreadWrapper::CreateThread(
      &LockUnlockThenStopRunFunction, &count);
  unsigned int id = 42;
  crit_sect->Enter();
  ASSERT_TRUE(thread->Start(id));
  SwitchProcess();
  // The critical section is of reentrant mode, so this should not release
  // the lock, even though count.Count() locks and unlocks the critical section
  // again.
  // Thus, the thread should not be able to increment the count
  ASSERT_EQ(0, count.Count());
  crit_sect->Leave();  // This frees the thread to act.
  EXPECT_TRUE(WaitForCount(1, &count));
  EXPECT_TRUE(thread->Stop());
  delete thread;
  delete crit_sect;
}

bool LockUnlockRunFunction(void* obj) {
  ProtectedCount* the_count = static_cast<ProtectedCount*>(obj);
  the_count->Increment();
  SwitchProcess();
  return true;
}

TEST_F(CritSectTest, ThreadWakesTwice) {
  CriticalSectionWrapper* crit_sect =
      CriticalSectionWrapper::CreateCriticalSection();
  ProtectedCount count(crit_sect);
  ThreadWrapper* thread = ThreadWrapper::CreateThread(&LockUnlockRunFunction,
                                                      &count);
  unsigned int id = 42;
  crit_sect->Enter();  // Make sure counter stays 0 until we wait for it.
  ASSERT_TRUE(thread->Start(id));
  crit_sect->Leave();

  // The thread is capable of grabbing the lock multiple times,
  // incrementing counter once each time.
  // It's possible for the count to be incremented by more than 2.
  EXPECT_TRUE(WaitForCount(2, &count));
  EXPECT_LE(2, count.Count());

  // The thread does not increment while lock is held.
  crit_sect->Enter();
  int count_before = count.Count();
  for (int i = 0; i < 10; i++) {
    SwitchProcess();
  }
  EXPECT_EQ(count_before, count.Count());
  crit_sect->Leave();

  thread->SetNotAlive();  // Tell thread to exit once run function finishes.
  SwitchProcess();
  EXPECT_TRUE(WaitForCount(count_before + 1, &count));
  EXPECT_TRUE(thread->Stop());
  delete thread;
  delete crit_sect;
}

}  // anonymous namespace

}  // namespace webrtc
<|endoftext|>


<commit_before>#include "Mass.h"
#include <meshing/VolumeGrid.h>
#include <meshing/Voxelize.h>
#include <errors.h>
using namespace Meshing;
using namespace Geometry;

const static Real third = 1.0/3.0;

//m = m+xy^t
inline void AddOuterProduct(Matrix3& m,const Vector3& x,const Vector3& y)
{
  //note that the matrix data variable is column-major, not row major
  m.data[0][0]+=x.x*y.x;
  m.data[0][1]+=x.y*y.x;
  m.data[0][2]+=x.z*y.x;

  m.data[1][0]+=x.x*y.y;
  m.data[1][1]+=x.y*y.y;
  m.data[1][2]+=x.z*y.y;

  m.data[2][0]+=x.x*y.z;
  m.data[2][1]+=x.y*y.z;
  m.data[2][2]+=x.z*y.z;
}

//first and second moments integrated over mesh
Vector3 CenterOfMass(const TriMesh& mesh)
{
  Triangle3D tri;
  Vector3 center(Zero);
  if(mesh.tris.empty()) return center;
  Real sumArea=Zero;
  for(size_t i=0;i<mesh.tris.size();i++) {
    mesh.GetTriangle(i,tri);
    Real area=tri.area();
    center.madd(tri.a+tri.b+tri.c,area*third);
    sumArea += area;
  }
  Assert(sumArea != Zero);
  center /= sumArea;
  return center;
}

Vector3 CenterOfMass(const Meshing::PointCloud3D& pc)
{
  Vector3 center(Zero);
  for(size_t i=0;i<pc.points.size();i++)
    center += pc.points[i];
  return center / pc.points.size();
}

Vector3 CenterOfMass(const Meshing::VolumeGrid& grid)
{
  Vector3 mean(Zero);
  Real sum=0;
  for(VolumeGridIterator<Real> i=grid.getIterator();!i.isDone();++i) {
    if(*i <= 0) {
      Vector3 c;
      i.getCellCenter(c);
      sum += 1.0;
      mean += *c;
    }
  }
  if(sum == 0) return mean;
  return mean / sum;
}

Vector3 CenterOfMass(const AnyGeometry3D& geom)
{
  switch(geom.type) {
  case AnyGeometry3D::Primitive:
    return CenterOfMass(*AnyCast<GeometricPrimitive3D>(&geom.data));
  case AnyGeometry3D::TriangleMesh:
    return CenterOfMass(*AnyCast<Meshing::TriMesh>(&geom.data));
  case AnyGeometry3D::PointCloud:
    return CenterOfMass(*AnyCast<Meshing::PointCloud3D>(&geom.data));
  case AnyGeometry3D::ImplicitSurface:
    return CenterOfMass(*AnyCast<Meshing::VolumeGrid>(&geom.data));
  }
  return Vector3();
}

Matrix3 Covariance(const TriMesh& mesh,const Vector3& center)
{
  Triangle3D tri;
  Real sumArea=Zero;
  Matrix3 A,temp;
  A.setZero();
  if(mesh.tris.empty()) return A;
  for(size_t i=0;i<mesh.tris.size();i++) {
    mesh.GetTriangle(i,tri);
    tri.a-=center;
    tri.b-=center;
    tri.c-=center;
    temp.setZero();
    AddOuterProduct(temp,tri.a,Two*tri.a+tri.b+tri.c);
    AddOuterProduct(temp,tri.b,Two*tri.b+tri.a+tri.c);
    AddOuterProduct(temp,tri.c,Two*tri.c+tri.a+tri.b);
    Real area = tri.area();
    temp *= area;
    A += temp;
    sumArea += area;
  }
  Assert(sumArea != Zero);
  A *= 1.0/sumArea;
  return A;
}

Matrix3 Covariance(const PointCloud3D& pc,const Vector3& center)
{
  Matrix3 A;
  A.setZero();
  if(pc.points.empty()) return A;
  for(size_t i=0;i<pc.points.size();i++) {
    AddOuterProduct(A,pc.points[i]-center,pc.points[i]-center);
  }
  A *= 1.0/pc.points.size();
  return A;
}

Matrix3 Covariance(const VolumeGrid& grid,const Vector3& center)
{
  Matrix3 cov(Zero);
  Real sum=0;
  for(VolumeGridIterator<Real> i=grid.getIterator();!i.isDone();++i) {
    if(*i <= 0) {
      Vector3 c;
      i.getCellCenter(c);
      Matrix3 temp; temp.setZero();
      AddOuterProduct(temp,c-center,c-center);
      cov += temp;
      sum += 1.0;
    }
  }
  if(sum == 0) return cov;
  cov *= 1.0/sum;
  return cov;
}

Matrix3 Covariance(const GeometricPrimitive3D& geom,const Vector3& center)
{
  FatalError("Covariance of primitives not done yet");
  return Matrix3();
}

Matrix3 Covariance(const AnyGeometry3D& geom,const Vector3& center)
{
  switch(geom.type) {
  case AnyGeometry3D::Primitive:
    return Covariance(*AnyCast<GeometricPrimitive3D>(&geom.data),center);
  case AnyGeometry3D::TriangleMesh:
    return Covariance(*AnyCast<Meshing::TriMesh>(&geom.data),center);
  case AnyGeometry3D::PointCloud:
    return Covariance(*AnyCast<Meshing::PointCloud3D>(&geom.data),center);
  case AnyGeometry3D::ImplicitSurface:
    return Covariance(*AnyCast<Meshing::VolumeGrid>(&geom.data),center);
  }
  return Matrix3();
}

Matrix3 Inertia(const TriMesh& mesh,const Vector3& center,Real mass)
{
  Matrix3 cov=Covariance(mesh,center);
  Matrix3 H;
  H.setNegative(cov);
  H(0,0) = cov(1,1)+cov(2,2);
  H(1,1) = cov(0,0)+cov(2,2);
  H(2,2) = cov(0,0)+cov(1,1);
  H *= mass;
  return H;
}

Matrix3 Inertia(const PointCloud3D& mesh,const Vector3& center,Real mass)
{
  Matrix3 cov=Covariance(mesh,center);
  Matrix3 H;
  H.setNegative(cov);
  H(0,0) = cov(1,1)+cov(2,2);
  H(1,1) = cov(0,0)+cov(2,2);
  H(2,2) = cov(0,0)+cov(1,1);
  H *= mass;
  return H;
}

Matrix3 Inertia(const VolumeGrid& mesh,const Vector3& center,Real mass)
{
  Matrix3 cov=Covariance(mesh,center);
  Matrix3 H;
  H.setNegative(cov);
  H(0,0) = cov(1,1)+cov(2,2);
  H(1,1) = cov(0,0)+cov(2,2);
  H(2,2) = cov(0,0)+cov(1,1);
  H *= mass;
  return H;
}

Matrix3 Inertia(const AnyGeometry3D& geom,const Vector3& center,Real mass)
{
  switch(geom.type) {
  case AnyGeometry3D::Primitive:
    return Inertia(*AnyCast<GeometricPrimitive3D>(&geom.data),center,mass);
  case AnyGeometry3D::TriangleMesh:
    return Inertia(*AnyCast<Meshing::TriMesh>(&geom.data),center,mass);
  case AnyGeometry3D::PointCloud:
    return Inertia(*AnyCast<Meshing::PointCloud3D>(&geom.data),center,mass);
  case AnyGeometry3D::ImplicitSurface:
    return Inertia(*AnyCast<Meshing::VolumeGrid>(&geom.data),center,mass);
  }
  return Matrix3();
}

///Computes the first moment integrated over the solid inside the mesh
///using a grid approximation
Vector3 CenterOfMass_Solid(const Meshing::TriMesh& mesh,Real gridRes)
{
  VolumeGrid grid;
  mesh.GetAABB(grid.bb.bmin,grid.bb.bmax);
  //expand slightly
  grid.bb.bmin -= Vector3(0.5*gridRes);
  grid.bb.bmax += Vector3(0.5*gridRes);
  grid.ResizeByResolution(Vector3(gridRes));
  DensityEstimate_CenterShooting(mesh,grid.value,grid.bb);
  Vector3 mean(Zero);
  Real sum=0;
  for(VolumeGridIterator<Real> i=grid.getIterator();!i.isDone();++i) {
    Vector3 c;
    i.getCellCenter(c);
    sum += *i;
    mean += *i*c;
  }
  if(sum == 0) return mean;
  mean /= sum;
  return mean;
}

///Computes the first moment integrated over the solid inside the mesh
///using a grid approximation
Matrix3 Covariance_Solid(const Meshing::TriMesh& mesh,Real gridRes,const Vector3& center)
{
  VolumeGrid grid;
  mesh.GetAABB(grid.bb.bmin,grid.bb.bmax);
  //expand slightly
  grid.bb.bmin -= Vector3(0.5*gridRes);
  grid.bb.bmax += Vector3(0.5*gridRes);
  grid.ResizeByResolution(Vector3(gridRes));
  DensityEstimate_CenterShooting(mesh,grid.value,grid.bb);
  Matrix3 cov(Zero);
  Real sum=0;
  for(VolumeGridIterator<Real> i=grid.getIterator();!i.isDone();++i) {
    Vector3 c;
    i.getCellCenter(c);
    Matrix3 temp; temp.setZero();
    AddOuterProduct(temp,c-center,c-center);
    temp *= *i;
    cov += temp;
    sum += *i;
  }
  if(sum == 0) return cov;
  cov *= 1.0/sum;
  return cov;
}

Matrix3 Inertia_Solid(const TriMesh& mesh,Real gridRes,const Vector3& center,Real mass)
{
  Matrix3 cov=Covariance_Solid(mesh,gridRes,center);
  Matrix3 H;
  H.setNegative(cov);
  H(0,0) = cov(1,1)+cov(2,2);
  H(1,1) = cov(0,0)+cov(2,2);
  H(2,2) = cov(0,0)+cov(1,1);
  H *= mass;
  return H;
}
<commit_msg>Added functions for Group geometries<commit_after>#include "Mass.h"
#include <meshing/VolumeGrid.h>
#include <meshing/Voxelize.h>
#include <errors.h>
using namespace Meshing;
using namespace Geometry;

const static Real third = 1.0/3.0;

//m = m+xy^t
inline void AddOuterProduct(Matrix3& m,const Vector3& x,const Vector3& y)
{
  //note that the matrix data variable is column-major, not row major
  m.data[0][0]+=x.x*y.x;
  m.data[0][1]+=x.y*y.x;
  m.data[0][2]+=x.z*y.x;

  m.data[1][0]+=x.x*y.y;
  m.data[1][1]+=x.y*y.y;
  m.data[1][2]+=x.z*y.y;

  m.data[2][0]+=x.x*y.z;
  m.data[2][1]+=x.y*y.z;
  m.data[2][2]+=x.z*y.z;
}

//first and second moments integrated over mesh
Vector3 CenterOfMass(const TriMesh& mesh)
{
  Triangle3D tri;
  Vector3 center(Zero);
  if(mesh.tris.empty()) return center;
  Real sumArea=Zero;
  for(size_t i=0;i<mesh.tris.size();i++) {
    mesh.GetTriangle(i,tri);
    Real area=tri.area();
    center.madd(tri.a+tri.b+tri.c,area*third);
    sumArea += area;
  }
  Assert(sumArea != Zero);
  center /= sumArea;
  return center;
}

Vector3 CenterOfMass(const Meshing::PointCloud3D& pc)
{
  Vector3 center(Zero);
  for(size_t i=0;i<pc.points.size();i++)
    center += pc.points[i];
  return center / pc.points.size();
}

Vector3 CenterOfMass(const Meshing::VolumeGrid& grid)
{
  Vector3 mean(Zero);
  Real sum=0;
  for(VolumeGridIterator<Real> i=grid.getIterator();!i.isDone();++i) {
    if(*i <= 0) {
      Vector3 c;
      i.getCellCenter(c);
      sum += 1.0;
      mean += *c;
    }
  }
  if(sum == 0) return mean;
  return mean / sum;
}

Vector3 CenterOfMass(const vector<AnyGeometry3D>& group)
{
  Vector3 sum(0.0);
  if(group.empty()) return sum;
  for(size_t i=0;i<group.size();i++)
    sum += CenterOfMass(group[i]);
  return sum / group.size();
}

Vector3 CenterOfMass(const AnyGeometry3D& geom)
{
  switch(geom.type) {
  case AnyGeometry3D::Primitive:
    return CenterOfMass(geom.AsPrimitive());
  case AnyGeometry3D::TriangleMesh:
    return CenterOfMass(geom.AsTriangleMesh());
  case AnyGeometry3D::PointCloud:
    return CenterOfMass(geom.AsPointCloud());
  case AnyGeometry3D::ImplicitSurface:
    return CenterOfMass(geom.AsImplicitSurface());
  case AnyGeometry3D::Group:
    return CenterOfMass(geom.AsGroup());
  }
  return Vector3(0.0);
}

Matrix3 Covariance(const TriMesh& mesh,const Vector3& center)
{
  Triangle3D tri;
  Real sumArea=Zero;
  Matrix3 A,temp;
  A.setZero();
  if(mesh.tris.empty()) return A;
  for(size_t i=0;i<mesh.tris.size();i++) {
    mesh.GetTriangle(i,tri);
    tri.a-=center;
    tri.b-=center;
    tri.c-=center;
    temp.setZero();
    AddOuterProduct(temp,tri.a,Two*tri.a+tri.b+tri.c);
    AddOuterProduct(temp,tri.b,Two*tri.b+tri.a+tri.c);
    AddOuterProduct(temp,tri.c,Two*tri.c+tri.a+tri.b);
    Real area = tri.area();
    temp *= area;
    A += temp;
    sumArea += area;
  }
  Assert(sumArea != Zero);
  A *= 1.0/sumArea;
  return A;
}

Matrix3 Covariance(const PointCloud3D& pc,const Vector3& center)
{
  Matrix3 A;
  A.setZero();
  if(pc.points.empty()) return A;
  for(size_t i=0;i<pc.points.size();i++) {
    AddOuterProduct(A,pc.points[i]-center,pc.points[i]-center);
  }
  A *= 1.0/pc.points.size();
  return A;
}

Matrix3 Covariance(const VolumeGrid& grid,const Vector3& center)
{
  Matrix3 cov(Zero);
  Real sum=0;
  for(VolumeGridIterator<Real> i=grid.getIterator();!i.isDone();++i) {
    if(*i <= 0) {
      Vector3 c;
      i.getCellCenter(c);
      Matrix3 temp; temp.setZero();
      AddOuterProduct(temp,c-center,c-center);
      cov += temp;
      sum += 1.0;
    }
  }
  if(sum == 0) return cov;
  cov *= 1.0/sum;
  return cov;
}

Matrix3 Covariance(const GeometricPrimitive3D& geom,const Vector3& center)
{
  FatalError("Covariance of primitives not done yet");
  return Matrix3();
}

Matrix3 Covariance(const vector<AnyGeometry3D>& group,const Vector3& center)
{
  Matrix3 res(0.0);
  for(size_t i=0;i<group.size();i++)
    res += Covariance(group[i],center);
  return res;
}

Matrix3 Covariance(const AnyGeometry3D& geom,const Vector3& center)
{
  switch(geom.type) {
  case AnyGeometry3D::Primitive:
    return Covariance(geom.AsPrimitive(),center);
  case AnyGeometry3D::TriangleMesh:
    return Covariance(geom.AsTriangleMesh(),center);
  case AnyGeometry3D::PointCloud:
    return Covariance(geom.AsPointCloud(),center);
  case AnyGeometry3D::ImplicitSurface:
    return Covariance(geom.AsImplicitSurface(),center);
  case AnyGeometry3D::Group:
    return Covariance(geom.AsGroup(),center);
  }
  return Matrix3();
}

Matrix3 Inertia(const TriMesh& mesh,const Vector3& center,Real mass)
{
  Matrix3 cov=Covariance(mesh,center);
  Matrix3 H;
  H.setNegative(cov);
  H(0,0) = cov(1,1)+cov(2,2);
  H(1,1) = cov(0,0)+cov(2,2);
  H(2,2) = cov(0,0)+cov(1,1);
  H *= mass;
  return H;
}

Matrix3 Inertia(const PointCloud3D& mesh,const Vector3& center,Real mass)
{
  Matrix3 cov=Covariance(mesh,center);
  Matrix3 H;
  H.setNegative(cov);
  H(0,0) = cov(1,1)+cov(2,2);
  H(1,1) = cov(0,0)+cov(2,2);
  H(2,2) = cov(0,0)+cov(1,1);
  H *= mass;
  return H;
}

Matrix3 Inertia(const VolumeGrid& mesh,const Vector3& center,Real mass)
{
  Matrix3 cov=Covariance(mesh,center);
  Matrix3 H;
  H.setNegative(cov);
  H(0,0) = cov(1,1)+cov(2,2);
  H(1,1) = cov(0,0)+cov(2,2);
  H(2,2) = cov(0,0)+cov(1,1);
  H *= mass;
  return H;
}

Matrix3 Inertia(const vector<AnyGeometry3D>& group,const Vector3& center,Real mass)
{
  Matrix3 cov=Covariance(group,center);
  Matrix3 H;
  H.setNegative(cov);
  H(0,0) = cov(1,1)+cov(2,2);
  H(1,1) = cov(0,0)+cov(2,2);
  H(2,2) = cov(0,0)+cov(1,1);
  H *= mass;
  return H;
}

Matrix3 Inertia(const AnyGeometry3D& geom,const Vector3& center,Real mass)
{
  switch(geom.type) {
  case AnyGeometry3D::Primitive:
    return Inertia(geom.AsPrimitive(),center,mass);
  case AnyGeometry3D::TriangleMesh:
    return Inertia(geom.AsTriangleMesh(),center,mass);
  case AnyGeometry3D::PointCloud:
    return Inertia(geom.AsPointCloud(),center,mass);
  case AnyGeometry3D::ImplicitSurface:
    return Inertia(geom.AsImplicitSurface(),center,mass);
  case AnyGeometry3D::Group:
    return Inertia(geom.AsGroup(),center,mass);
  }
  return Matrix3();
}

///Computes the first moment integrated over the solid inside the mesh
///using a grid approximation
Vector3 CenterOfMass_Solid(const Meshing::TriMesh& mesh,Real gridRes)
{
  VolumeGrid grid;
  mesh.GetAABB(grid.bb.bmin,grid.bb.bmax);
  //expand slightly
  grid.bb.bmin -= Vector3(0.5*gridRes);
  grid.bb.bmax += Vector3(0.5*gridRes);
  grid.ResizeByResolution(Vector3(gridRes));
  DensityEstimate_CenterShooting(mesh,grid.value,grid.bb);
  Vector3 mean(Zero);
  Real sum=0;
  for(VolumeGridIterator<Real> i=grid.getIterator();!i.isDone();++i) {
    Vector3 c;
    i.getCellCenter(c);
    sum += *i;
    mean += *i*c;
  }
  if(sum == 0) return mean;
  mean /= sum;
  return mean;
}

///Computes the first moment integrated over the solid inside the mesh
///using a grid approximation
Matrix3 Covariance_Solid(const Meshing::TriMesh& mesh,Real gridRes,const Vector3& center)
{
  VolumeGrid grid;
  mesh.GetAABB(grid.bb.bmin,grid.bb.bmax);
  //expand slightly
  grid.bb.bmin -= Vector3(0.5*gridRes);
  grid.bb.bmax += Vector3(0.5*gridRes);
  grid.ResizeByResolution(Vector3(gridRes));
  DensityEstimate_CenterShooting(mesh,grid.value,grid.bb);
  Matrix3 cov(Zero);
  Real sum=0;
  for(VolumeGridIterator<Real> i=grid.getIterator();!i.isDone();++i) {
    Vector3 c;
    i.getCellCenter(c);
    Matrix3 temp; temp.setZero();
    AddOuterProduct(temp,c-center,c-center);
    temp *= *i;
    cov += temp;
    sum += *i;
  }
  if(sum == 0) return cov;
  cov *= 1.0/sum;
  return cov;
}

Matrix3 Inertia_Solid(const TriMesh& mesh,Real gridRes,const Vector3& center,Real mass)
{
  Matrix3 cov=Covariance_Solid(mesh,gridRes,center);
  Matrix3 H;
  H.setNegative(cov);
  H(0,0) = cov(1,1)+cov(2,2);
  H(1,1) = cov(0,0)+cov(2,2);
  H(2,2) = cov(0,0)+cov(1,1);
  H *= mass;
  return H;
}
<|endoftext|>


<commit_before>/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.

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 "tensorflow/core/framework/common_shape_fns.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/shape_inference.h"
#include "tensorflow/core/lib/core/status.h"

namespace tensorflow {

using shape_inference::InferenceContext;
using shape_inference::ShapeHandle;

// Configuring a distributed TPU system is achieved by running
// the following Ops:
//
// 1 Run _DisconnectHostFromDistributedTPUSystem on the CPU of each
// host. This is needed in case the system had previously been
// configured. It returns, for each host, the number of TPU chips on
// the host.
//
// 2 Run _ConfigureDistributedTPU on TPU_SYSTEM. Takes as input the
// number of chips on each host. Validates that all hosts have the
// same number of chips, and that the chips are consistent with the
// topology set by flags. Has a single output which is a proto
// describing the requested system configuration, which is sent to all
// hosts.
//
// 3 Run _InitializeHostForDistributedTPU on the CPU of each host,
// taking as input the output from ConfigureDistributedTPU. Has a
// single Tensor output which is a vector of int32 indicating, for
// each TPU on the host, what its global TPU system id is.
//
// 4 Run _WaitForDistributedTPU on TPU_SYSTEM, taking as input the
// outputs from all the _InitializeHostForDistributedTPU
// Ops. _WaitForDistributedTPU has an attr host_specs which is a
// vector<string> giving the partial device spec for each host. These
// partial specs are combined in the Op with the outputs from the host
// initialization Ops to construct a mapping from full TPU device
// specs to global TPU ids. Has a single Tensor output which is a
// matrix of int32 indicating, for each host (outer dimension) and for
// each TPU on the host (inner dimension) what that TPU's global id
// is. _WaitForDistributedTPU also waits for the TPU distributed
// system to initialize fully, which may take several minutes for a
// large system.
//
// 5 Run _SetGlobalTPUArray on the CPU of each host, taking as input
// the output from _WaitForDistributedTPU. This Op tells each host the
// global Id of every TPU on every host.
//
// Most user code works by placing the ConfigureDistributedTPU Op on
// the desired TPU_SYSTEM device, and a graph rewrite replaces it by
// the subgraph described above.
//
//
// A distributed TPU system can be cleanly shut down by running
// the following Ops:
//
// 1 Run _DisconnectHostFromDistributedTPUSystem on the CPU of each
// host.
//
// 2 Run _ShutdownDistributedTPU on the TPU_SYSTEM where
// _ConfigureDistributedTPU was run. The Op will return an error if no
// system is configured.
//
//
// Most user code works by placing the ShutdownDistributedTPU Op on
// the desired TPU_SYSTEM device, and a graph rewrite replaces it by
// the subgraph described above.

REGISTER_OP("_ConfigureDistributedTPU")
    .Input("inputs: N * int32")
    .Output("output: string")
    .Attr("N: int >= 1")
    .SetIsStateful()
    .SetShapeFn([](InferenceContext* c) {
      ShapeHandle input;
      // Validate that all the inputs are scalars.
      for (int i = 0; i < c->num_inputs(); ++i) {
        TF_RETURN_IF_ERROR(c->WithRank(c->input(i), 0, &input));
      }
      c->set_output(0, c->Scalar());
      return Status::OK();
    })
    .Doc(R"doc(
An op that sets up the centralized structures for a distributed TPU
system.

inputs: A scalar tensor for each host indicating how many TPU chips
there are on the host.
output: A tensor containing a TPUHostConfiguration proto serialized to
a string, containing the information necessary to initialize the chips
in a host.
)doc");

REGISTER_OP("_WaitForDistributedTPU")
    .Input("inputs: N * int32")
    .Output("topology: string")
    .Attr("host_specs: list(string)")
    .Attr("startup_timeout_sec: int = 20")
    .Attr("N: int")
    .SetIsStateful()
    .SetShapeFn([](InferenceContext* c) {
      ShapeHandle input;
      // Validate that all the inputs have the same vector shape.
      for (int i = 0; i < c->num_inputs(); ++i) {
        TF_RETURN_IF_ERROR(c->WithRank(c->input(i), 1, &input));
      }
      c->set_output(0, c->Scalar());
      return ::tensorflow::Status::OK();
    })
    .Doc(R"doc(
An op that blocks execution until a distributed TPU system has
started up. This Op must be run on the same TPU_SYSTEM device as
_ConfigureDistributedTPU, and takes an inputs the outputs from the
_InitializeHostForDistributedTPU Ops.

inputs: For each initialized host, a vector giving the global TPU id
of each TPU on the host.
topology: A serialized tensorflow.tpu.TopologyProto that describes the TPU
topology.
startup_timeout_sec: The number of seconds to wait for the TPU system
to stabilize.
)doc");

REGISTER_OP("_SetGlobalTPUArray")
    .Input("topology: string")
    .SetIsStateful()
    .SetShapeFn([](InferenceContext* c) {
      ShapeHandle input;
      TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 0, &input));
      return ::tensorflow::Status::OK();
    })
    .Doc(R"doc(
An op that informs a host of the global ids of all the of TPUs in the
system.

topology: A serialized tensorflow.tpu.TopologyProto that describes the TPU
topology.
)doc");

REGISTER_OP("_ShutdownDistributedTPU")
    .SetIsStateful()
    .SetShapeFn(shape_inference::UnknownShape)
    .Doc(R"doc(
An op that shuts down a running distributed TPU system. The Op returns
an error if no system is running. This Op must be run on the same
TPU_SYSTEM device as the corresponding _ConfigureDistributedTPU was run
to start the system, and must be run only after
_DisconnectHostFromDistributedTPUSystem has completed on every host in
the system.
)doc");

REGISTER_OP("_InitializeHostForDistributedTPU")
    .Input("input: string")
    .Output("tpu_ids: int32")
    .SetIsStateful()
    .SetShapeFn([](InferenceContext* c) {
      ShapeHandle input;
      TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 0, &input));
      c->set_output(0, c->Vector(c->UnknownDim()));
      return ::tensorflow::Status::OK();
    })
    .Doc(R"doc(
An op that connects each chip on the host to a centralized UberDriver to allow
them to operate as a distributed system with chips in other hosts.

input: A string containing the address of the UberDriver to connect to.
tpu_ids: A vector containing the global TPU id of each TPU on the host.
)doc");

REGISTER_OP("_DisconnectHostFromDistributedTPUSystem")
    .Output("number_of_tpu_chips: int32")
    .SetIsStateful()
    .SetShapeFn(shape_inference::UnknownShape)
    .Doc(R"doc(
An op that disconnects the TPUs on a host from a running distributed
TPU system.

number_of_tpu_chips: A scalar tensor containing the number of TPU
chips on the host.
)doc");

REGISTER_OP("ConfigureDistributedTPU")
    .Output("topology: string")
    .Attr("embedding_config: string = ''")
    .SetIsStateful()
    .SetShapeFn(shape_inference::UnknownShape)
    .Doc(R"doc(
An op that sets up the centralized structures for a distributed TPU
system.

topology: A serialized tensorflow.tpu.TopologyProto that describes the TPU
topology.
)doc");

REGISTER_OP("ShutdownDistributedTPU")
    .SetIsStateful()
    .SetShapeFn(shape_inference::UnknownShape)
    .Doc(R"doc(
An op that shuts down a running distributed TPU system. The Op returns
an error if no system is running.
)doc");

}  // namespace tensorflow
<commit_msg>Remove host_spec attr from TPU configuration ops since it isn't used any more.<commit_after>/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.

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 "tensorflow/core/framework/common_shape_fns.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/shape_inference.h"
#include "tensorflow/core/lib/core/status.h"

namespace tensorflow {

using shape_inference::InferenceContext;
using shape_inference::ShapeHandle;

// Configuring a distributed TPU system is achieved by running
// the following Ops:
//
// 1 Run _DisconnectHostFromDistributedTPUSystem on the CPU of each
// host. This is needed in case the system had previously been
// configured. It returns, for each host, the number of TPU chips on
// the host.
//
// 2 Run _ConfigureDistributedTPU on TPU_SYSTEM. Takes as input the
// number of chips on each host. Validates that all hosts have the
// same number of chips, and that the chips are consistent with the
// topology set by flags. Has a single output which is a proto
// describing the requested system configuration, which is sent to all
// hosts.
//
// 3 Run _InitializeHostForDistributedTPU on the CPU of each host,
// taking as input the output from ConfigureDistributedTPU. Has a
// single Tensor output which is a vector of int32 indicating, for
// each TPU on the host, what its global TPU system id is.
//
// 4 Run _WaitForDistributedTPU on TPU_SYSTEM, taking as input the
// outputs from all the _InitializeHostForDistributedTPU
// Ops. _These partial specs are combined in the Op with the outputs from
// the host initialization Ops to construct a mapping from full TPU device
// specs to global TPU ids. Has a single Tensor output which is a
// matrix of int32 indicating, for each host (outer dimension) and for
// each TPU on the host (inner dimension) what that TPU's global id
// is. _WaitForDistributedTPU also waits for the TPU distributed
// system to initialize fully, which may take several minutes for a
// large system.
//
// 5 Run _SetGlobalTPUArray on the CPU of each host, taking as input
// the output from _WaitForDistributedTPU. This Op tells each host the
// global Id of every TPU on every host.
//
// Most user code works by placing the ConfigureDistributedTPU Op on
// the desired TPU_SYSTEM device, and a graph rewrite replaces it by
// the subgraph described above.
//
//
// A distributed TPU system can be cleanly shut down by running
// the following Ops:
//
// 1 Run _DisconnectHostFromDistributedTPUSystem on the CPU of each
// host.
//
// 2 Run _ShutdownDistributedTPU on the TPU_SYSTEM where
// _ConfigureDistributedTPU was run. The Op will return an error if no
// system is configured.
//
//
// Most user code works by placing the ShutdownDistributedTPU Op on
// the desired TPU_SYSTEM device, and a graph rewrite replaces it by
// the subgraph described above.

REGISTER_OP("_ConfigureDistributedTPU")
    .Input("inputs: N * int32")
    .Output("output: string")
    .Attr("N: int >= 1")
    .SetIsStateful()
    .SetShapeFn([](InferenceContext* c) {
      ShapeHandle input;
      // Validate that all the inputs are scalars.
      for (int i = 0; i < c->num_inputs(); ++i) {
        TF_RETURN_IF_ERROR(c->WithRank(c->input(i), 0, &input));
      }
      c->set_output(0, c->Scalar());
      return Status::OK();
    })
    .Doc(R"doc(
An op that sets up the centralized structures for a distributed TPU
system.

inputs: A scalar tensor for each host indicating how many TPU chips
there are on the host.
output: A tensor containing a TPUHostConfiguration proto serialized to
a string, containing the information necessary to initialize the chips
in a host.
)doc");

REGISTER_OP("_WaitForDistributedTPU")
    .Input("inputs: N * int32")
    .Output("topology: string")
    .Attr("startup_timeout_sec: int = 20")
    .Attr("N: int")
    .SetIsStateful()
    .SetShapeFn([](InferenceContext* c) {
      ShapeHandle input;
      // Validate that all the inputs have the same vector shape.
      for (int i = 0; i < c->num_inputs(); ++i) {
        TF_RETURN_IF_ERROR(c->WithRank(c->input(i), 1, &input));
      }
      c->set_output(0, c->Scalar());
      return ::tensorflow::Status::OK();
    })
    .Doc(R"doc(
An op that blocks execution until a distributed TPU system has
started up. This Op must be run on the same TPU_SYSTEM device as
_ConfigureDistributedTPU, and takes an inputs the outputs from the
_InitializeHostForDistributedTPU Ops.

inputs: For each initialized host, a vector giving the global TPU id
of each TPU on the host.
topology: A serialized tensorflow.tpu.TopologyProto that describes the TPU
topology.
startup_timeout_sec: The number of seconds to wait for the TPU system
to stabilize.
)doc");

REGISTER_OP("_SetGlobalTPUArray")
    .Input("topology: string")
    .SetIsStateful()
    .SetShapeFn([](InferenceContext* c) {
      ShapeHandle input;
      TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 0, &input));
      return ::tensorflow::Status::OK();
    })
    .Doc(R"doc(
An op that informs a host of the global ids of all the of TPUs in the
system.

topology: A serialized tensorflow.tpu.TopologyProto that describes the TPU
topology.
)doc");

REGISTER_OP("_ShutdownDistributedTPU")
    .SetIsStateful()
    .SetShapeFn(shape_inference::UnknownShape)
    .Doc(R"doc(
An op that shuts down a running distributed TPU system. The Op returns
an error if no system is running. This Op must be run on the same
TPU_SYSTEM device as the corresponding _ConfigureDistributedTPU was run
to start the system, and must be run only after
_DisconnectHostFromDistributedTPUSystem has completed on every host in
the system.
)doc");

REGISTER_OP("_InitializeHostForDistributedTPU")
    .Input("input: string")
    .Output("tpu_ids: int32")
    .SetIsStateful()
    .SetShapeFn([](InferenceContext* c) {
      ShapeHandle input;
      TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 0, &input));
      c->set_output(0, c->Vector(c->UnknownDim()));
      return ::tensorflow::Status::OK();
    })
    .Doc(R"doc(
An op that connects each chip on the host to a centralized UberDriver to allow
them to operate as a distributed system with chips in other hosts.

input: A string containing the address of the UberDriver to connect to.
tpu_ids: A vector containing the global TPU id of each TPU on the host.
)doc");

REGISTER_OP("_DisconnectHostFromDistributedTPUSystem")
    .Output("number_of_tpu_chips: int32")
    .SetIsStateful()
    .SetShapeFn(shape_inference::UnknownShape)
    .Doc(R"doc(
An op that disconnects the TPUs on a host from a running distributed
TPU system.

number_of_tpu_chips: A scalar tensor containing the number of TPU
chips on the host.
)doc");

REGISTER_OP("ConfigureDistributedTPU")
    .Output("topology: string")
    .Attr("embedding_config: string = ''")
    .SetIsStateful()
    .SetShapeFn(shape_inference::UnknownShape)
    .Doc(R"doc(
An op that sets up the centralized structures for a distributed TPU
system.

topology: A serialized tensorflow.tpu.TopologyProto that describes the TPU
topology.
)doc");

REGISTER_OP("ShutdownDistributedTPU")
    .SetIsStateful()
    .SetShapeFn(shape_inference::UnknownShape)
    .Doc(R"doc(
An op that shuts down a running distributed TPU system. The Op returns
an error if no system is running.
)doc");

}  // namespace tensorflow
<|endoftext|>