diff --git a/CMakeLists.txt b/CMakeLists.txt index 06eaae4..ea2d54c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,12 +153,14 @@ IF ( FIELDML_BUILD_JAVA ) SET_SOURCE_FILES_PROPERTIES(jni/fieldml_io.i PROPERTIES CPLUSPLUS ON) # If you change these version, also change the .i files. - SWIG_ADD_MODULE(fieldml_jni_0.4 java jni/fieldml_api.i) - SWIG_LINK_LIBRARIES(fieldml_jni_0.4 fieldml_api fieldml_io_api) + SWIG_ADD_MODULE(fieldml_jni_0.5 java jni/fieldml_api.i) + SWIG_ADD_MODULE(fieldml_io_0.5 java jni/fieldml_io.i) + SWIG_LINK_LIBRARIES(fieldml_jni_0.5 fieldml_api fieldml_io_api) + SWIG_LINK_LIBRARIES(fieldml_io_0.5 fieldml_api fieldml_io_api) # Also make the jar file... - SET(javafiles "fieldml/jni/FieldmlApiConstants.java;fieldml/jni/FieldmlApi.java;fieldml/jni/FieldmlApiJNI.java;fieldml/jni/FieldmlDataDescriptionType.java;fieldml/jni/FieldmlDataResourceType.java;fieldml/jni/FieldmlDataSourceType.java;fieldml/jni/FieldmlEnsembleMembersType.java;fieldml/jni/FieldmlHandleType.java;fieldml/jni/FieldmlIoConstants.java;fieldml/jni/FieldmlIo.java;fieldml/jni/FieldmlIoJNI.java;fieldml/jni/SWIGTYPE_p_FmlBoolean.java;fieldml/jni/SWIGTYPE_p_FmlObjectHandle.java;fieldml/jni/SWIGTYPE_p_FmlSessionHandle.java;fieldml/jni/SWIGTYPE_p_int32_t.java") - SET(classfiles "fieldml/jni/FieldmlApi.class;fieldml/jni/FieldmlApiConstants.class;fieldml/jni/FieldmlApiJNI.class;fieldml/jni/FieldmlDataDescriptionType.class;fieldml/jni/FieldmlDataDescriptionType\\$$SwigNext.class;fieldml/jni/FieldmlDataResourceType.class;fieldml/jni/FieldmlDataResourceType\\$$SwigNext.class;fieldml/jni/FieldmlDataSourceType.class;fieldml/jni/FieldmlDataSourceType\\$$SwigNext.class;fieldml/jni/FieldmlEnsembleMembersType.class;fieldml/jni/FieldmlEnsembleMembersType\\$$SwigNext.class;fieldml/jni/FieldmlHandleType.class;fieldml/jni/FieldmlHandleType\\$$SwigNext.class;fieldml/jni/FieldmlIo.class;fieldml/jni/FieldmlIoConstants.class;fieldml/jni/FieldmlIoJNI.class;fieldml/jni/SWIGTYPE_p_FmlBoolean.class;fieldml/jni/SWIGTYPE_p_FmlObjectHandle.class;fieldml/jni/SWIGTYPE_p_FmlSessionHandle.class;fieldml/jni/SWIGTYPE_p_int32_t.class") + SET(javafiles "fieldml/jni/FieldmlApiConstants.java;fieldml/jni/FieldmlApi.java;fieldml/jni/FieldmlApiJNI.java;fieldml/jni/FieldmlDataDescriptionType.java;fieldml/jni/FieldmlDataResourceType.java;fieldml/jni/FieldmlDataSourceType.java;fieldml/jni/FieldmlEnsembleMembersType.java;fieldml/jni/FieldmlHandleType.java;fieldml/jni/FieldmlIo.java;fieldml/jni/FieldmlIoJNI.java;fieldml/jni/SWIGTYPE_p_FmlBoolean.java;fieldml/jni/SWIGTYPE_p_FmlObjectHandle.java;fieldml/jni/SWIGTYPE_p_FmlSessionHandle.java;fieldml/jni/SWIGTYPE_p_int32_t.java") + SET(classfiles "fieldml/jni/FieldmlApi.class;fieldml/jni/FieldmlApiConstants.class;fieldml/jni/FieldmlApiJNI.class;fieldml/jni/FieldmlDataDescriptionType.class;fieldml/jni/FieldmlDataDescriptionType\\$$SwigNext.class;fieldml/jni/FieldmlDataResourceType.class;fieldml/jni/FieldmlDataResourceType\\$$SwigNext.class;fieldml/jni/FieldmlDataSourceType.class;fieldml/jni/FieldmlDataSourceType\\$$SwigNext.class;fieldml/jni/FieldmlEnsembleMembersType.class;fieldml/jni/FieldmlEnsembleMembersType\\$$SwigNext.class;fieldml/jni/FieldmlHandleType.class;fieldml/jni/FieldmlHandleType\\$$SwigNext.class;fieldml/jni/FieldmlIoConstants.class;fieldml/jni/FieldmlIo.class;fieldml/jni/FieldmlIoConstants.class;fieldml/jni/FieldmlIoJNI.class;fieldml/jni/SWIGTYPE_p_FmlBoolean.class;fieldml/jni/SWIGTYPE_p_FmlObjectHandle.class;fieldml/jni/SWIGTYPE_p_FmlSessionHandle.class;fieldml/jni/SWIGTYPE_p_int32_t.class") ADD_CUSTOM_COMMAND(OUTPUT ${classfiles} COMMAND ${Java_JAVAC_EXECUTABLE} ARGS ${javafiles} diff --git a/FieldML_Library.xml b/FieldML_Library.xml index 131d976..b6c73f0 100644 --- a/FieldML_Library.xml +++ b/FieldML_Library.xml @@ -281,10 +281,84 @@ + + + + + + + + + + + + 1 1 1 1 1 1 1 1 + 2 2 2 2 2 2 2 2 + 3 3 3 3 3 3 3 3 + 4 4 4 4 4 4 4 4 + 5 5 5 5 5 5 5 5 + 6 6 6 6 6 6 6 6 + 7 7 7 7 7 7 7 7 + 8 8 8 8 8 8 8 8 + + + + 64 + + + + + + + 0 1 2 3 4 5 6 7 + 0 1 2 3 4 5 6 7 + 0 1 2 3 4 5 6 7 + 0 1 2 3 4 5 6 7 + 0 1 2 3 4 5 6 7 + 0 1 2 3 4 5 6 7 + 0 1 2 3 4 5 6 7 + 0 1 2 3 4 5 6 7 + + + + 64 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/src/Evaluators.cpp b/core/src/Evaluators.cpp index ee7c1fa..a25e71c 100644 --- a/core/src/Evaluators.cpp +++ b/core/src/Evaluators.cpp @@ -66,9 +66,9 @@ template T *checkedCast(FieldmlSession *session, const FmlObjectHan } //End namespace EvaluatorsUtil -Evaluator::Evaluator( const string _name, FieldmlHandleType _type, FmlObjectHandle _valueType, bool _isVirtual ) : - FieldmlObject( _name, _type, _isVirtual ), - valueType( _valueType ) +Evaluator::Evaluator( const std::string _name, FieldmlRegion* _region, FieldmlHandleType _type, FmlObjectHandle _valueType, bool _isVirtual ) : + FieldmlObject( _name, _region, _type, _isVirtual ), + valueType( _valueType ) { } @@ -96,9 +96,9 @@ Evaluator *Evaluator::checkedCast( FieldmlSession *session, FmlObjectHandle obje } -ConstantEvaluator::ConstantEvaluator( const string _name, const string _valueString, FmlObjectHandle _valueType ) : - Evaluator( _name, FHT_CONSTANT_EVALUATOR, _valueType, false ), - valueString( _valueString ) +ConstantEvaluator::ConstantEvaluator( const std::string _name, FieldmlRegion* _region, const string _valueString, FmlObjectHandle _valueType ) : + Evaluator( _name, _region, FHT_CONSTANT_EVALUATOR, _valueType, false ), + valueString( _valueString ) { } @@ -115,10 +115,14 @@ ConstantEvaluator *ConstantEvaluator::checkedCast( FieldmlSession *session, FmlO } -ReferenceEvaluator::ReferenceEvaluator( const string _name, FmlObjectHandle _evaluator, FmlObjectHandle _valueType, bool _isVirtual ) : - Evaluator( _name, FHT_REFERENCE_EVALUATOR, _valueType, _isVirtual ), - sourceEvaluator( _evaluator ), - binds( FML_INVALID_HANDLE ) +ReferenceEvaluator::ReferenceEvaluator +( + const std::string _name, + FieldmlRegion* _region, + FmlObjectHandle _evaluator, FmlObjectHandle _valueType, bool _isVirtual ) : + Evaluator( _name, _region, FHT_REFERENCE_EVALUATOR, _valueType, _isVirtual ), + sourceEvaluator( _evaluator ), + binds( FML_INVALID_HANDLE ) { } @@ -140,8 +144,9 @@ ReferenceEvaluator *ReferenceEvaluator::checkedCast( FieldmlSession *session, Fm } -ArgumentEvaluator::ArgumentEvaluator( const string _name, FmlObjectHandle _valueType, bool _isVirtual ) : - Evaluator( _name, FHT_ARGUMENT_EVALUATOR, _valueType, _isVirtual ) +ArgumentEvaluator::ArgumentEvaluator(const std::string _name, FieldmlRegion* _region, + FmlObjectHandle _valueType, bool _isVirtual ) : + Evaluator( _name, _region, FHT_ARGUMENT_EVALUATOR, _valueType, _isVirtual ) { } @@ -158,8 +163,8 @@ ArgumentEvaluator *ArgumentEvaluator::checkedCast( FieldmlSession *session, FmlO } -ExternalEvaluator::ExternalEvaluator( const string _name, FmlObjectHandle _valueType, bool _isVirtual ) : - Evaluator( _name, FHT_EXTERNAL_EVALUATOR, _valueType, _isVirtual ) +ExternalEvaluator::ExternalEvaluator( const std::string _name, FieldmlRegion* _region, FmlObjectHandle _valueType, bool _isVirtual ) : + Evaluator( _name, _region, FHT_EXTERNAL_EVALUATOR, _valueType, _isVirtual ) { } @@ -176,8 +181,8 @@ ExternalEvaluator *ExternalEvaluator::checkedCast( FieldmlSession *session, FmlO } -ParameterEvaluator::ParameterEvaluator( const string _name, FmlObjectHandle _valueType, bool _isVirtual ) : - Evaluator( _name, FHT_PARAMETER_EVALUATOR, _valueType, _isVirtual ) +ParameterEvaluator::ParameterEvaluator( const std::string _name, FieldmlRegion* _region, FmlObjectHandle _valueType, bool _isVirtual ) : + Evaluator( _name, _region, FHT_PARAMETER_EVALUATOR, _valueType, _isVirtual ) { dataDescription = new UnknownDataDescription(); } @@ -203,11 +208,11 @@ ParameterEvaluator *ParameterEvaluator::checkedCast( FieldmlSession *session, Fm } -PiecewiseEvaluator::PiecewiseEvaluator( const string _name, FmlObjectHandle _valueType, bool _isVirtual ) : - Evaluator( _name, FHT_PIECEWISE_EVALUATOR, _valueType, _isVirtual ), - binds( FML_INVALID_HANDLE ), - evaluators( FML_INVALID_HANDLE ), - indexEvaluator( FML_INVALID_HANDLE ) +PiecewiseEvaluator::PiecewiseEvaluator( const std::string _name, FieldmlRegion* _region, FmlObjectHandle _valueType, bool _isVirtual ) : + Evaluator( _name, _region, FHT_PIECEWISE_EVALUATOR, _valueType, _isVirtual ), + binds( FML_INVALID_HANDLE ), + evaluators( FML_INVALID_HANDLE ), + indexEvaluator( FML_INVALID_HANDLE ) { } @@ -232,11 +237,11 @@ PiecewiseEvaluator *PiecewiseEvaluator::checkedCast( FieldmlSession *session, Fm } -AggregateEvaluator::AggregateEvaluator( const string _name, FmlObjectHandle _valueType, bool _isVirtual ) : - Evaluator( _name, FHT_AGGREGATE_EVALUATOR, _valueType, _isVirtual ), - binds( FML_INVALID_HANDLE ), - evaluators( FML_INVALID_HANDLE ), - indexEvaluator( FML_INVALID_HANDLE ) +AggregateEvaluator::AggregateEvaluator( const std::string _name, FieldmlRegion* _region, FmlObjectHandle _valueType, bool _isVirtual ) : + Evaluator( _name, _region, FHT_AGGREGATE_EVALUATOR, _valueType, _isVirtual ), + binds( FML_INVALID_HANDLE ), + evaluators( FML_INVALID_HANDLE ), + indexEvaluator( FML_INVALID_HANDLE ) { } diff --git a/core/src/Evaluators.h b/core/src/Evaluators.h index 694040f..4cf3d14 100644 --- a/core/src/Evaluators.h +++ b/core/src/Evaluators.h @@ -57,7 +57,7 @@ class Evaluator : public: const FmlObjectHandle valueType; - Evaluator( const std::string _name, FieldmlHandleType _type, FmlObjectHandle _valueType, bool _isVirtual ); + Evaluator( const std::string _name, FieldmlRegion* _region, FieldmlHandleType _type, FmlObjectHandle _valueType, bool _isVirtual ); virtual bool addDelegates( std::set &delegates ) = 0; @@ -71,7 +71,7 @@ class ConstantEvaluator : public: const std::string valueString; - ConstantEvaluator( const std::string _name, const std::string _literal, FmlObjectHandle _valueType ); + ConstantEvaluator( const std::string _name, FieldmlRegion* _region, const std::string _literal, FmlObjectHandle _valueType ); virtual bool addDelegates( std::set &delegates ); @@ -87,7 +87,7 @@ class ReferenceEvaluator : SimpleMap binds; - ReferenceEvaluator( const std::string _name, FmlObjectHandle _evaluator, FmlObjectHandle _valueType, bool _isVirtual ); + ReferenceEvaluator( const std::string _name, FieldmlRegion* _region, FmlObjectHandle _evaluator, FmlObjectHandle _valueType, bool _isVirtual ); virtual bool addDelegates( std::set &delegates ); @@ -104,7 +104,7 @@ class PiecewiseEvaluator : SimpleMap binds; SimpleMap evaluators; - PiecewiseEvaluator( const std::string name, FmlObjectHandle valueType, bool _isVirtual ); + PiecewiseEvaluator( const std::string name, FieldmlRegion* region, FmlObjectHandle valueType, bool _isVirtual ); virtual bool addDelegates( std::set &delegates ); @@ -121,7 +121,7 @@ class AggregateEvaluator : FmlObjectHandle indexEvaluator; - AggregateEvaluator( const std::string _name, FmlObjectHandle _valueType, bool _isVirtual ); + AggregateEvaluator( const std::string _name, FieldmlRegion* _region, FmlObjectHandle _valueType, bool _isVirtual ); virtual bool addDelegates( std::set &delegates ); @@ -135,7 +135,7 @@ class ArgumentEvaluator : public: std::set arguments; - ArgumentEvaluator( const std::string name, FmlObjectHandle _valueType, bool _isVirtual ); + ArgumentEvaluator( const std::string name, FieldmlRegion* region, FmlObjectHandle _valueType, bool _isVirtual ); virtual bool addDelegates( std::set &delegates ); @@ -149,7 +149,7 @@ class ExternalEvaluator : public: std::set arguments; - ExternalEvaluator( const std::string name, FmlObjectHandle _valueType, bool _isVirtual ); + ExternalEvaluator( const std::string name, FieldmlRegion* region, FmlObjectHandle _valueType, bool _isVirtual ); virtual bool addDelegates( std::set &delegates ); @@ -163,7 +163,7 @@ class ParameterEvaluator : public: BaseDataDescription *dataDescription; - ParameterEvaluator( const std::string _name, FmlObjectHandle _valueType, bool _isVirtual ); + ParameterEvaluator( const std::string _name, FieldmlRegion* _region, FmlObjectHandle _valueType, bool _isVirtual ); virtual bool addDelegates( std::set &delegates ); diff --git a/core/src/FieldmlDOM.cpp b/core/src/FieldmlDOM.cpp index 2516442..4f3b8c0 100644 --- a/core/src/FieldmlDOM.cpp +++ b/core/src/FieldmlDOM.cpp @@ -41,7 +41,7 @@ #include #include -#include +#include #include #include @@ -66,13 +66,13 @@ struct ParseState { FmlSessionHandle session; FieldmlErrorHandler *errorHandler; - vector parseStack; - vector unparsedNodes; + std::list parseStack; + std::list unparsedNodes; //14102011 CPL Currently, mesh shapes depends on an evaluator which typically depends on mesh-argument which depends on mesh. //To work around this cyclic dependency, the shapes attribute is analysed after rest of the document has been parsed. //In the long term, shapes will be a bound-type property of a mesh-type domain, so the problem will neatly vanish. - vector > shapesHACK; + std::list > shapesHACK; }; //======================================================================== @@ -203,7 +203,7 @@ FmlObjectHandle getObjectAttribute( xmlNodePtr node, const xmlChar *attribute, P return FML_INVALID_HANDLE; } - for( vector::iterator i = state.unparsedNodes.begin(); i != state.unparsedNodes.end(); i++ ) + for( std::list::iterator i = state.unparsedNodes.begin(); i != state.unparsedNodes.end(); i++ ) { const char *nodeObjectName = getStringAttribute( *i, NAME_ATTRIB ); if( strcmp( objectName, nodeObjectName ) == 0 ) @@ -387,7 +387,7 @@ class IntVectorParser : ~IntVectorParser() { - delete values; + delete [] values; } }; @@ -1426,7 +1426,7 @@ static int parseObjectNode( xmlNodePtr objectNode, ParseState &state ) state.parseStack.pop_back(); - vector::iterator loc = find( state.unparsedNodes.begin(), state.unparsedNodes.end(), objectNode ); + std::list::iterator loc = find( state.unparsedNodes.begin(), state.unparsedNodes.end(), objectNode ); state.unparsedNodes.erase( loc ); @@ -1453,7 +1453,7 @@ static int parseDataNode( xmlNodePtr objectNode, ParseState &state ) state.parseStack.pop_back(); - vector::iterator loc = find( state.unparsedNodes.begin(), state.unparsedNodes.end(), objectNode ); + std::list::iterator loc = find( state.unparsedNodes.begin(), state.unparsedNodes.end(), objectNode ); state.unparsedNodes.erase( loc ); @@ -1490,10 +1490,12 @@ static int parseDoc( xmlDocPtr doc, ParseState &state ) // To be improved: Required the following "for" loop to loop through all the top level elements and // parse the data resources before anything using them. - for( vector::iterator j = state.unparsedNodes.begin(); j != state.unparsedNodes.end();) + bool isEnd = state.unparsedNodes.empty(); + for( std::list::iterator j = state.unparsedNodes.begin(); !isEnd;) { xmlNodePtr temp_node = *j; j++; + isEnd = j == state.unparsedNodes.end(); parseDataNode( temp_node, state ); } @@ -1502,7 +1504,7 @@ static int parseDoc( xmlDocPtr doc, ParseState &state ) parseObjectNode( state.unparsedNodes.back(), state ); } - for( vector >::const_iterator i = state.shapesHACK.begin(); i != state.shapesHACK.end(); i++ ) + for( std::list >::const_iterator i = state.shapesHACK.begin(); i != state.shapesHACK.end(); i++ ) { FmlObjectHandle shapesEvaluator = Fieldml_GetObjectByName( state.session, i->second.c_str() ); if( Fieldml_SetMeshShapes( state.session, i->first, shapesEvaluator ) != FML_ERR_NO_ERROR ) diff --git a/core/src/FieldmlSession.cpp b/core/src/FieldmlSession.cpp index c583b42..af984a4 100644 --- a/core/src/FieldmlSession.cpp +++ b/core/src/FieldmlSession.cpp @@ -115,6 +115,13 @@ FieldmlRegion *FieldmlSession::getRegion( string href, string name ) return NULL; } +FieldmlRegion *FieldmlSession::getRegion(std::string href) +{ + for (std::vector::iterator i = regions.begin(); i != regions.end(); i++) + if ((*i)->getHref() == href) + return *i; + return NULL; +} FieldmlRegion *FieldmlSession::addNewRegion( string href, string name ) { diff --git a/core/src/FieldmlSession.h b/core/src/FieldmlSession.h index b9261eb..0d44f07 100644 --- a/core/src/FieldmlSession.h +++ b/core/src/FieldmlSession.h @@ -120,6 +120,7 @@ class FieldmlSession : FieldmlRegion *addNewRegion( std::string location, std::string name ); FieldmlRegion *getRegion( std::string location, std::string name ); + FieldmlRegion *getRegion( std::string location ); int getRegionIndex( std::string location, std::string name ); diff --git a/core/src/fieldml_api.cpp b/core/src/fieldml_api.cpp index 02c5707..a54992f 100644 --- a/core/src/fieldml_api.cpp +++ b/core/src/fieldml_api.cpp @@ -1,4076 +1,4110 @@ -/* \file - * $Id$ - * \author Caton Little - * \brief - * - * \section LICENSE - * - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - * License for the specific language governing rights and limitations - * under the License. - * - * The Original Code is FieldML - * - * The Initial Developer of the Original Code is Auckland Uniservices Ltd, - * Auckland, New Zealand. Portions created by the Initial Developer are - * Copyright (C) 2010 the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - */ - -#include - -#include - -#include "String_InternalLibrary.h" - -#include "fieldml_api.h" -#include "FieldmlSession.h" -#include "ErrorContextAutostack.h" -#include "fieldml_structs.h" -#include "Evaluators.h" -#include "fieldml_write.h" -#include "string_const.h" -#include "Util.h" - -#include "FieldmlRegion.h" - -using namespace std; - -//======================================================================== -// -// Utility -// -// NOTE: A number of these methods are just wrappers around FieldmlSession -// methods, but which also set error codes. Methods such as FieldmlSession::getObject -// should not set error codes themselves, as failure is not necessarily an error. -// -//======================================================================== - -static FieldmlObject *getObject( FieldmlSession *session, FmlObjectHandle objectHandle ) -{ - ERROR_AUTOSTACK( session ); - - FieldmlObject *object = session->getObject( objectHandle ); - - if( object == NULL ) - { - session->setError( FML_ERR_UNKNOWN_OBJECT, "Invalid object handle." ); - } - - return object; -} - - -static bool checkLocal( FieldmlSession *session, FmlObjectHandle objectHandle ) -{ - ERROR_AUTOSTACK( session ); - - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region." ); - return false; - } - - if( objectHandle == FML_INVALID_HANDLE ) - { - //Nano-hack. Makes checking legitimate FML_INVALID_HANDLE parameters easier. - return true; - } - - if( !session->region->hasLocalObject( objectHandle, true, true ) ) - { - session->setError( FML_ERR_NONLOCAL_OBJECT, objectHandle, "Not a local object." ); - return false; - } - - return true; -} - - -static FmlObjectHandle addObject( FieldmlSession *session, FieldmlObject *object ) -{ - ERROR_AUTOSTACK( session ); - - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); - return FML_INVALID_HANDLE; - } - - FmlObjectHandle handle = session->region->getNamedObject( object->name.c_str() ); - - if( handle == FML_INVALID_HANDLE ) - { - FmlObjectHandle handle = session->objects.addObject( object ); - session->region->addLocalObject( handle ); - return handle; - } - - FieldmlObject *oldObject = session->objects.getObject( handle ); - - session->logError( "Handle collision. Cannot replace", object->name.c_str(), oldObject->name.c_str() ); - delete object; - - session->setError( FML_ERR_NAME_COLLISION, "There is already an object named " + object->name + " in this scope." ); - - return FML_INVALID_HANDLE; -} - - -static SimpleMap *getEvaluatorMap( FieldmlSession *session, FmlObjectHandle objectHandle ) -{ - ERROR_AUTOSTACK( session ); - - FieldmlObject *object = getObject( session, objectHandle ); - if( object == NULL ) - { - return NULL; - } - - AggregateEvaluator *aggregate = AggregateEvaluator::checkedCast( session, objectHandle ); - if( aggregate != NULL ) - { - return &aggregate->evaluators; - } - - PiecewiseEvaluator *piecewise = PiecewiseEvaluator::checkedCast( session, objectHandle ); - if( piecewise != NULL ) - { - return &piecewise->evaluators; - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must either be a Piecewise or Aggregate evaluator." ); - return NULL; -} - - -static SimpleMap *getBindMap( FieldmlSession *session, FmlObjectHandle objectHandle ) -{ - ERROR_AUTOSTACK( session ); - - FieldmlObject *object = getObject( session, objectHandle ); - if( object == NULL ) - { - return NULL; - } - - AggregateEvaluator *aggregate = AggregateEvaluator::checkedCast( session, objectHandle ); - if( aggregate != NULL ) - { - return &aggregate->binds; - } - - PiecewiseEvaluator *piecewise = PiecewiseEvaluator::checkedCast( session, objectHandle ); - if( piecewise != NULL ) - { - return &piecewise->binds; - } - - ReferenceEvaluator *reference = ReferenceEvaluator::checkedCast( session, objectHandle ); - if( reference != NULL ) - { - return &reference->binds; - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an Aggregate, Piecewise or Reference evaluator." ); - return NULL; -} - - -static vector getArgumentList( FieldmlSession *session, FmlObjectHandle objectHandle, bool isBound, bool isUsed ) -{ - vector args; - - ERROR_AUTOSTACK( session ); - - FieldmlObject *object = getObject( session, objectHandle ); - if( object == NULL ) - { - return args; - } - - Evaluator *evaluator = Evaluator::checkedCast( session, objectHandle ); - - if( evaluator == NULL ) - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get arguments. Must be an evalator." ); - return args; - } - - if ( isBound && !isUsed ) - { - //Always an empty set with the current algorithm, as it only tracks unbound or used arguments. - return args; - } - if( !isBound && !isUsed ) - { - //Always an empty set with the current algorithm, as it assumes that arguments of arguments are used. - return args; - } - - set unbound, used; - session->getArguments( objectHandle, unbound, used, false ); - - if( isBound && isUsed ) - { - for( set::const_iterator i = used.begin(); i != used.end(); i++ ) - { - // Performance wise, I am not sure I should remove all elems from - // unbound in used or using find as shown below. - if (unbound.end() == unbound.find(*i)) - args.push_back( *i ); - } - return args; - } - else //if( !isBound && isUsed ) - { - //In used, and in unbound. Unbound is always is a subset of used with the current algorithm. - for( set::const_iterator i = unbound.begin(); i != unbound.end(); i++ ) - { - args.push_back( *i ); - } - return args; - } -} - - -static bool checkCyclicDependency( FieldmlSession *session, FmlObjectHandle objectHandle, FmlObjectHandle objectDependancy ) -{ - ERROR_AUTOSTACK( session ); - - set delegates; - session->getDelegateEvaluators( objectDependancy, delegates ); - if( FmlUtil::contains( delegates, objectHandle ) ) - { - session->setError( FML_ERR_CYCLIC_DEPENDENCY, objectHandle, "Cyclic dependancy." ); - return false; - } - - return true; -} - - -static char* cstrCopy( const string &s ) -{ - return strdupS( s.c_str() ); -} - -static int cappedCopy( const char * source, char * buffer, int bufferLength ) -{ - if( ( bufferLength <= 1 ) || ( source == NULL ) ) - { - return 0; - } - - int length = strlen( source ); - - if( length >= bufferLength ) - { - length = ( bufferLength - 1 ); - } - - memcpy( buffer, source, length ); - buffer[length] = 0; - - return length; -} - - -static int cappedCopyAndFree( const char * source, char * buffer, int bufferLength ) -{ - int length = cappedCopy( source, buffer, bufferLength ); - free( (void*)source ); - return length; -} - - -static DataSource *objectAsDataSource( FieldmlSession *session, FmlObjectHandle objectHandle ) -{ - ERROR_AUTOSTACK( session ); - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - return NULL; - } - - if( object->objectType != FHT_DATA_SOURCE ) - { - session->setError( FML_ERR_INVALID_OBJECT, "Must be a data source." ); - return NULL; - } - - return (DataSource*)object; -} - - -static ArrayDataSource *getArrayDataSource( FieldmlSession *session, FmlObjectHandle objectHandle ) -{ - ERROR_AUTOSTACK( session ); - - DataSource *dataSource = objectAsDataSource( session, objectHandle ); - - if( dataSource == NULL ) - { - return NULL; - } - - if( dataSource->sourceType != FML_DATA_SOURCE_ARRAY ) - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an array data source." ); - return NULL; - } - - ArrayDataSource *arraySource = (ArrayDataSource*)dataSource; - return arraySource; -} - - -static DataResource *getDataResource( FieldmlSession *session, FmlObjectHandle objectHandle ) -{ - ERROR_AUTOSTACK( session ); - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - return NULL; - } - - if( object->objectType != FHT_DATA_RESOURCE ) - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a data resource." ); - return NULL; - } - - return (DataResource*)object; -} - - -static bool checkIsValueType( FieldmlSession *session, FmlObjectHandle objectHandle, bool allowContinuous, bool allowEnsemble, bool allowMesh, bool allowBoolean ) -{ - ERROR_AUTOSTACK( session ); - - FieldmlObject *object = getObject( session, objectHandle ); - if( object == NULL ) - { - return false; - } - - switch( object->objectType ) - { - case FHT_CONTINUOUS_TYPE: - return allowContinuous; - case FHT_ENSEMBLE_TYPE: - return allowEnsemble; - case FHT_MESH_TYPE: - return allowMesh; - case FHT_BOOLEAN_TYPE: - return allowBoolean; - default: - return false; - } -} - - -static bool checkIsEvaluatorType( FieldmlSession *session, FmlObjectHandle objectHandle, bool allowContinuous, bool allowEnsemble, bool allowBoolean ) -{ - ERROR_AUTOSTACK( session ); - - Evaluator *evaluator = Evaluator::checkedCast( session, objectHandle ); - if( evaluator == NULL ) - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Is not an evaluator." ); - return false; - } - - return checkIsValueType( session, evaluator->valueType, allowContinuous, allowEnsemble, false, allowBoolean ); -} - - -static bool checkIsTypeCompatible( FieldmlSession *session, FmlObjectHandle objectHandle1, FmlObjectHandle objectHandle2 ) -{ - ERROR_AUTOSTACK( session ); - - if( !checkIsValueType( session, objectHandle1, true, true, false, true ) ) - { - return false; - } - if( !checkIsValueType( session, objectHandle2, true, true, false, true ) ) - { - return false; - } - - FieldmlObject *object1 = getObject( session, objectHandle1 ); - FieldmlObject *object2 = getObject( session, objectHandle2 ); - - if( object1->objectType != object2->objectType ) - { - return false; - } - else if( object1->objectType == FHT_BOOLEAN_TYPE ) - { - return true; - } - else if( object1->objectType == FHT_ENSEMBLE_TYPE ) - { - return objectHandle1 == objectHandle2; - } - else if( object1->objectType == FHT_CONTINUOUS_TYPE ) - { - FmlObjectHandle component1 = Fieldml_GetTypeComponentEnsemble( session->getSessionHandle(), objectHandle1 ); - FmlObjectHandle component2 = Fieldml_GetTypeComponentEnsemble( session->getSessionHandle(), objectHandle2 ); - - if( ( component1 == FML_INVALID_HANDLE ) && ( component2 == FML_INVALID_HANDLE ) ) - { - return true; - } - else if( ( component1 == FML_INVALID_HANDLE ) || ( component2 == FML_INVALID_HANDLE ) ) - { - return false; - } - - return Fieldml_GetTypeComponentCount( session->getSessionHandle(), objectHandle1 ) == Fieldml_GetTypeComponentCount( session->getSessionHandle(), objectHandle2 ); - } - else - { - return false; - } -} - - -static bool checkIsEvaluatorTypeCompatible( FieldmlSession *session, FmlObjectHandle objectHandle1, FmlObjectHandle objectHandle2 ) -{ - ERROR_AUTOSTACK( session ); - - if( !checkIsEvaluatorType( session, objectHandle1, true, true, true ) ) - { - return false; - } - if( !checkIsEvaluatorType( session, objectHandle2, true, true, true ) ) - { - return false; - } - - FmlObjectHandle typeHandle1 = Fieldml_GetValueType( session->getSessionHandle(), objectHandle1 ); - FmlObjectHandle typeHandle2 = Fieldml_GetValueType( session->getSessionHandle(), objectHandle2 ); - - return checkIsTypeCompatible( session, typeHandle1, typeHandle2 ); -} - - -//======================================================================== -// -// API -// -//======================================================================== - -FmlSessionHandle Fieldml_CreateFromFile( const char * filename ) -{ - FieldmlSession *session = new FieldmlSession(); - ErrorContextAutostack bob( session, __FILE__, __LINE__, __ECA_FUNC__ ); - - if( filename == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_1, "Cannot create FieldML session. Invalid filename." ); - } - else - { - session->region = session->addResourceRegion( filename, "" ); - if( session->region == NULL ) - { - session->setError( FML_ERR_READ_ERR, "Cannot create FieldML session. Invalid document or read error." ); - } - else - { - session->region->setRoot( getDirectory( filename ) ); - session->region->finalize(); - } - } - - return session->getSessionHandle(); -} - - -FmlSessionHandle Fieldml_Create( const char * location, const char * name ) -{ - FieldmlSession *session = new FieldmlSession(); - ERROR_AUTOSTACK( session ); - - if( location == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_1, "Cannot create FieldML session. Invalid location." ); - } - else if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create FieldML session. Invalid name." ); - } - else - { - session->region = session->addNewRegion( location, name ); - } - - return session->getSessionHandle(); -} - - -FmlErrorNumber Fieldml_SetDebug( FmlSessionHandle handle, int debug ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - session->setDebug( debug ); - - return session->setError( FML_ERR_NO_ERROR, "" ); -} - - -FmlErrorNumber Fieldml_GetLastError( FmlSessionHandle handle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - return session->getLastError(); -} - - -FmlErrorNumber Fieldml_WriteFile( FmlSessionHandle handle, const char * filename ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - if( session->region == NULL ) - { - return session->setError( FML_ERR_INVALID_REGION, "Cannot write FieldML file. FieldML session has no region." ); - } - if( filename == NULL ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot write FieldML file. Invalid filename." ); - } - - session->setError( FML_ERR_NO_ERROR, "" ); - session->region->setRoot( getDirectory( filename ) ); - - return writeFieldmlFile( session, handle, filename ); -} - - -void Fieldml_Destroy( FmlSessionHandle handle ) -{ - FieldmlSession::removeSession( handle ); -} - - -char * Fieldml_GetRegionName( FmlSessionHandle handle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return NULL; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "Cannot get region name. FieldML session has no region." ); - return NULL; - } - - session->setError( FML_ERR_NO_ERROR, "" ); - return cstrCopy( session->region->getName() ); -} - - -FmlErrorNumber Fieldml_FreeString( char * string ) -{ - if( string != NULL ) - { - free( string ); - } - - return FML_ERR_NO_ERROR; -} - - -int Fieldml_CopyRegionName( FmlSessionHandle handle, char * buffer, int bufferLength ) -{ - return cappedCopyAndFree( Fieldml_GetRegionName( handle ), buffer, bufferLength ); -} - - -char * Fieldml_GetRegionRoot( FmlSessionHandle handle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return NULL; - } - - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "Cannot get region root. FieldML session has no region." ); - return NULL; - } - - session->setError( FML_ERR_NO_ERROR, "" ); - return cstrCopy( session->region->getRoot() ); -} - - -int Fieldml_CopyRegionRoot( FmlSessionHandle handle, char * buffer, int bufferLength ) -{ - return cappedCopyAndFree( Fieldml_GetRegionRoot( handle ), buffer, bufferLength ); -} - - -int Fieldml_GetErrorCount( FmlSessionHandle handle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - session->setError( FML_ERR_NO_ERROR, "" ); - return session->getErrorCount(); -} - - -char * Fieldml_GetError( FmlSessionHandle handle, int index ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return NULL; - } - - session->setError( FML_ERR_NO_ERROR, "" ); - return cstrCopy( session->getError( index - 1 ) ); -} - - -int Fieldml_CopyError( FmlSessionHandle handle, int errorIndex, char * buffer, int bufferLength ) -{ - return cappedCopyAndFree( Fieldml_GetError( handle, errorIndex ), buffer, bufferLength ); -} - - -FmlErrorNumber Fieldml_ClearErrors( FmlSessionHandle handle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - session->clearErrors(); - return session->setError( FML_ERR_NO_ERROR, "" ); -} - - -int Fieldml_GetTotalObjectCount( FmlSessionHandle handle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - session->setError( FML_ERR_NO_ERROR, "" ); - return session->objects.getCount(); -} - - -FmlObjectHandle Fieldml_GetObjectByIndex( FmlSessionHandle handle, const int objectIndex ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - session->setError( FML_ERR_NO_ERROR, "" ); - return session->objects.getObjectByIndex( objectIndex ); -} - - -int Fieldml_GetObjectCount( FmlSessionHandle handle, FieldmlHandleType type ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - session->setError( FML_ERR_NO_ERROR, "" ); - if( type == FHT_UNKNOWN ) - { - return -1; - } - - return session->objects.getCount( type ); -} - - -FmlObjectHandle Fieldml_GetObject( FmlSessionHandle handle, FieldmlHandleType objectType, int objectIndex ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - session->setError( FML_ERR_NO_ERROR, "" ); - - FmlObjectHandle object = session->objects.getObjectByIndex( objectIndex, objectType ); - if( object == FML_INVALID_HANDLE ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, "Cannot get object by type. Invalid index." ); - } - - return object; -} - - -FmlObjectHandle Fieldml_GetObjectByName( FmlSessionHandle handle, const char * name ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "Cannot get object by local name. FieldML session has no region." ); - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot get object by local name. Invalid name." ); - return FML_INVALID_HANDLE; - } - - FmlObjectHandle object = session->region->getNamedObject( name ); - - return object; -} - - -FmlObjectHandle Fieldml_GetObjectByDeclaredName( FmlSessionHandle handle, const char * name ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot get object by declared name. Invalid name." ); - return FML_INVALID_HANDLE; - } - - FmlObjectHandle object = session->objects.getObjectByName( name ); - - return object; -} - - -FieldmlHandleType Fieldml_GetObjectType( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FHT_UNKNOWN; - } - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - return FHT_UNKNOWN; - } - - return object->objectType; -} - - -FmlObjectHandle Fieldml_GetTypeComponentEnsemble( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - return FML_INVALID_HANDLE; - } - - if( object->objectType == FHT_CONTINUOUS_TYPE ) - { - ContinuousType *continuousType = (ContinuousType*)object; - return continuousType->componentType; - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get component ensemble. Must be a type with components." ); - return FML_INVALID_HANDLE; -} - - -int Fieldml_GetTypeComponentCount( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - FmlObjectHandle componentTypeHandle = Fieldml_GetTypeComponentEnsemble( handle, objectHandle ); - - if( componentTypeHandle == FML_INVALID_HANDLE ) - { - if( session->getLastError() == FML_ERR_NO_ERROR ) - { - return 1; - } - return -1; - } - - return Fieldml_GetMemberCount( handle, componentTypeHandle ); -} - - -int Fieldml_GetMemberCount( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - return -1; - } - - if( object->objectType == FHT_ENSEMBLE_TYPE ) - { - EnsembleType *ensembleType = (EnsembleType*)object; - return ensembleType->count; - } - else if( object->objectType == FHT_MESH_TYPE ) - { - MeshType *meshType = (MeshType*)object; - return Fieldml_GetMemberCount( handle, meshType->elementsType ); - } - - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get member count. Must be a type with members/elements." ); - return -1; -} - - -FmlEnsembleValue Fieldml_GetEnsembleMembersMin( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - return -1; - } - - if( object->objectType == FHT_ENSEMBLE_TYPE ) - { - EnsembleType *ensembleType = (EnsembleType*)object; - return ensembleType->min; - } - else if( object->objectType == FHT_MESH_TYPE ) - { - MeshType *meshType = (MeshType*)object; - return Fieldml_GetEnsembleMembersMin( handle, meshType->elementsType ); - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an ensemble or mesh type." ); - return -1; -} - - -FmlEnsembleValue Fieldml_GetEnsembleMembersMax( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - return -1; - } - - if( object->objectType == FHT_ENSEMBLE_TYPE ) - { - EnsembleType *ensembleType = (EnsembleType*)object; - return ensembleType->max; - } - else if( object->objectType == FHT_MESH_TYPE ) - { - MeshType *meshType = (MeshType*)object; - return Fieldml_GetEnsembleMembersMax( handle, meshType->elementsType ); - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an ensemble or mesh type." ); - return -1; -} - - -int Fieldml_GetEnsembleMembersStride( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - return -1; - } - - if( object->objectType == FHT_ENSEMBLE_TYPE ) - { - EnsembleType *ensembleType = (EnsembleType*)object; - return ensembleType->stride; - } - else if( object->objectType == FHT_MESH_TYPE ) - { - MeshType *meshType = (MeshType*)object; - return Fieldml_GetEnsembleMembersStride( handle, meshType->elementsType ); - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an ensemble or mesh type." ); - return -1; -} - - -FieldmlEnsembleMembersType Fieldml_GetEnsembleMembersType( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ENSEMBLE_MEMBER_UNKNOWN; - } - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - return FML_ENSEMBLE_MEMBER_UNKNOWN; - } - - if( object->objectType == FHT_ENSEMBLE_TYPE ) - { - EnsembleType *ensembleType = (EnsembleType*)object; - return ensembleType->membersType; - } - else if( object->objectType == FHT_MESH_TYPE ) - { - MeshType *meshType = (MeshType *)object; - return Fieldml_GetEnsembleMembersType( handle, meshType->elementsType ); - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an ensemble or mesh type." ); - return FML_ENSEMBLE_MEMBER_UNKNOWN; -} - - -FmlErrorNumber Fieldml_SetEnsembleMembersDataSource( FmlSessionHandle handle, FmlObjectHandle objectHandle, FieldmlEnsembleMembersType type, int count, FmlObjectHandle dataSourceHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - if( !checkLocal( session, objectHandle ) ) - { - return session->getLastError(); - } - - if( Fieldml_GetObjectType( handle, dataSourceHandle ) != FHT_DATA_SOURCE ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_5, dataSourceHandle, "Must be a data source to be used for member labels." ); - } - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - return session->getLastError(); - } - else if( object->objectType == FHT_ENSEMBLE_TYPE ) - { - EnsembleType *ensembleType = (EnsembleType*)object; - - if( ( type != FML_ENSEMBLE_MEMBER_LIST_DATA ) && ( type != FML_ENSEMBLE_MEMBER_RANGE_DATA ) && ( type != FML_ENSEMBLE_MEMBER_STRIDE_RANGE_DATA ) ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Has a member type which cannot be used with a data source." ); - } - - ensembleType->membersType = type; - ensembleType->count = count; - ensembleType->dataSource = dataSourceHandle; - return session->getLastError(); - } - else if( object->objectType == FHT_MESH_TYPE ) - { - MeshType *meshType = (MeshType *)object; - return Fieldml_SetEnsembleMembersDataSource( handle, meshType->elementsType, type, count, dataSourceHandle ); - } - - return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an ensemble or mesh type." ); -} - - -FmlBoolean Fieldml_IsEnsembleComponentType( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - return -1; - } - - if( object->objectType == FHT_ENSEMBLE_TYPE ) - { - EnsembleType *ensembleType = (EnsembleType*)object; - return ensembleType->isComponentEnsemble; - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an ensemble type." ); - return -1; -} - - -FmlObjectHandle Fieldml_GetMeshElementsType( FmlSessionHandle handle, FmlObjectHandle meshHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - FieldmlObject *object = getObject( session, meshHandle ); - - if( object == NULL ) - { - return FML_INVALID_HANDLE; - } - if( object->objectType == FHT_MESH_TYPE ) - { - MeshType *meshType = (MeshType *)object; - return meshType->elementsType; - } - - session->setError( FML_ERR_INVALID_OBJECT, meshHandle, "Must be a mesh type." ); - return FML_INVALID_HANDLE; -} - - -FmlObjectHandle Fieldml_GetMeshShapes( FmlSessionHandle handle, FmlObjectHandle meshHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - FieldmlObject *object = getObject( session, meshHandle ); - - if( object == NULL ) - { - return FML_INVALID_HANDLE; - } - if( object->objectType == FHT_MESH_TYPE ) - { - MeshType *meshType = (MeshType *)object; - return meshType->shapes; - } - - session->setError( FML_ERR_INVALID_OBJECT, meshHandle, "Must be a mesh type." ); - return FML_INVALID_HANDLE; -} - - -FmlObjectHandle Fieldml_GetMeshChartType( FmlSessionHandle handle, FmlObjectHandle meshHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - FieldmlObject *object = getObject( session, meshHandle ); - - if( object == NULL ) - { - return FML_INVALID_HANDLE; - } - if( object->objectType == FHT_MESH_TYPE ) - { - MeshType *meshType = (MeshType *)object; - return meshType->chartType; - } - - session->setError( FML_ERR_INVALID_OBJECT, meshHandle, "Must be a mesh type." ); - return FML_INVALID_HANDLE; -} - - -FmlObjectHandle Fieldml_GetMeshChartComponentType( FmlSessionHandle handle, FmlObjectHandle meshHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - FieldmlObject *object = getObject( session, meshHandle ); - - if( object == NULL ) - { - return FML_INVALID_HANDLE; - } - if( object->objectType == FHT_MESH_TYPE ) - { - MeshType *meshType = (MeshType *)object; - return Fieldml_GetTypeComponentEnsemble( handle, meshType->chartType ); - } - - session->setError( FML_ERR_INVALID_OBJECT, meshHandle, "Must be a mesh type." ); - return FML_INVALID_HANDLE; -} - - -FmlBoolean Fieldml_IsObjectLocal( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlBoolean isDeclaredOnly ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); - return 0; - } - - bool allowVirtual = ( isDeclaredOnly != 1 ); - bool allowImport = ( isDeclaredOnly != 1 ); - if( session->region->hasLocalObject( objectHandle, allowVirtual, allowImport ) ) - { - return 1; - } - else - { - return 0; - } -} - - -char * Fieldml_GetObjectName( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return NULL; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); - return NULL; - } - - string name = session->region->getObjectName( objectHandle ); - if( name == "" ) - { - return NULL; - } - - return cstrCopy( name.c_str() ); -} - - -int Fieldml_CopyObjectName( FmlSessionHandle handle, FmlObjectHandle objectHandle, char * buffer, int bufferLength ) -{ - return cappedCopyAndFree( Fieldml_GetObjectName( handle, objectHandle ), buffer, bufferLength ); -} - - -char * Fieldml_GetObjectDeclaredName( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return NULL; - } - - FieldmlObject *object = session->objects.getObject( objectHandle ); - if( object == NULL ) - { - return NULL; - } - - return cstrCopy( object->name.c_str() ); -} - - -int Fieldml_CopyObjectDeclaredName( FmlSessionHandle handle, FmlObjectHandle objectHandle, char * buffer, int bufferLength ) -{ - return cappedCopyAndFree( Fieldml_GetObjectDeclaredName( handle, objectHandle ), buffer, bufferLength ); -} - - -FmlErrorNumber Fieldml_SetObjectInt( FmlSessionHandle handle, FmlObjectHandle objectHandle, int value ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - return session->getLastError(); - } - - object->intValue = value; - return session->getLastError(); -} - - -int Fieldml_GetObjectInt( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return 0; - } - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - return 0; - } - - return object->intValue; -} - - -FmlObjectHandle Fieldml_GetValueType( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - Evaluator *evaluator = Evaluator::checkedCast( session, objectHandle ); - if( evaluator != NULL ) - { - return evaluator->valueType; - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an evaluator." ); - return FML_INVALID_HANDLE; -} - - -FmlObjectHandle Fieldml_CreateArgumentEvaluator( FmlSessionHandle handle, const char * name, FmlObjectHandle valueType ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Invalid argument evaluator name." ); - return FML_INVALID_HANDLE; - } - - if( !checkLocal( session, valueType ) ) - { - return session->getLastError(); - } - - if( !checkIsValueType( session, valueType, true, true, true, true ) ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, valueType, "Invalid value type for argument evaluator " + string( name ) ); - return FML_INVALID_HANDLE; - } - - //TODO Icky hack to auto-add mesh type subevaluators. Subevaluators need to either be first-class objects, or - //specified at bind-time. - if( Fieldml_GetObjectType( handle, valueType ) == FHT_MESH_TYPE ) - { - FmlObjectHandle chartType = Fieldml_GetMeshChartType( handle, valueType ); - FmlObjectHandle elementsType = Fieldml_GetMeshElementsType( handle, valueType ); - - string meshName = session->region->getObjectName( valueType ); - meshName += "."; - - string argumentName = name; - string chartComponentName = session->region->getObjectName( chartType ); - string elementsComponentName = session->region->getObjectName( elementsType ); - - string chartSuffix = "chart"; - if( chartComponentName.compare( 0, meshName.length(), meshName ) == 0 ) - { - chartSuffix = chartComponentName.substr( meshName.length(), chartComponentName.length() ); - } - string chartName = argumentName + "." + chartSuffix; - - if( Fieldml_GetObjectByName( handle, chartName.c_str() ) != FML_INVALID_HANDLE ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, valueType, "Cannot create mesh argument evaluator. " + chartName + " already exists." ); - return FML_INVALID_HANDLE; - } - - string elementsSuffix = "elements"; - if( elementsComponentName.compare( 0, meshName.length(), meshName ) == 0 ) - { - elementsSuffix = elementsComponentName.substr( meshName.length(), elementsComponentName.length() ); - } - string elementsName = argumentName + "." + elementsSuffix; - - if( Fieldml_GetObjectByName( handle, elementsName.c_str() ) != FML_INVALID_HANDLE ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, valueType, "Cannot create mesh argument evaluator. " + elementsName + " already exists." ); - return FML_INVALID_HANDLE; - } - - //Shouldn't need to check for name-collision, as we already have. - ArgumentEvaluator *chartEvaluator = new ArgumentEvaluator( chartName.c_str(), chartType, true ); - addObject( session, chartEvaluator ); - - ArgumentEvaluator *elementEvaluator = new ArgumentEvaluator( elementsName.c_str(), elementsType, true ); - addObject( session, elementEvaluator ); - } - - ArgumentEvaluator *argumentEvaluator = new ArgumentEvaluator( name, valueType, false ); - - session->setError( FML_ERR_NO_ERROR, "" ); - return addObject( session, argumentEvaluator ); -} - - -FmlObjectHandle Fieldml_CreateExternalEvaluator( FmlSessionHandle handle, const char * name, FmlObjectHandle valueType ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create external evaluator. Invalid name." ); - return FML_INVALID_HANDLE; - } - - if( !checkLocal( session, valueType ) ) - { - return session->getLastError(); - } - - if( !checkIsValueType( session, valueType, true, true, false, true ) ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, valueType, "Cannot create external evaluator of this type." ); - return FML_INVALID_HANDLE; - } - - ExternalEvaluator *externalEvaluator = new ExternalEvaluator( name, valueType, false ); - - session->setError( FML_ERR_NO_ERROR, "" ); - return addObject( session, externalEvaluator ); -} - - -FmlObjectHandle Fieldml_CreateParameterEvaluator( FmlSessionHandle handle, const char * name, FmlObjectHandle valueType ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create parameter evaluator. Invalid name." ); - return FML_INVALID_HANDLE; - } - - if( !checkLocal( session, valueType ) ) - { - return session->getLastError(); - } - - if( !checkIsValueType( session, valueType, true, true, false, true ) ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, valueType, "Cannot create parameter evaluator of this type." ); - return FML_INVALID_HANDLE; - } - - ParameterEvaluator *parameterEvaluator = new ParameterEvaluator( name, valueType, false ); - - session->setError( FML_ERR_NO_ERROR, "" ); - return addObject( session, parameterEvaluator ); -} - - -FmlErrorNumber Fieldml_SetParameterDataDescription( FmlSessionHandle handle, FmlObjectHandle objectHandle, FieldmlDataDescriptionType description ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - if( !checkLocal( session, objectHandle ) ) - { - return session->getLastError(); - } - - ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); - if( parameter != NULL ) - { - if( parameter->dataDescription->descriptionType != FML_DATA_DESCRIPTION_UNKNOWN ) - { - return session->setError( FML_ERR_ACCESS_VIOLATION, objectHandle, "Parameter evaluator already has a data description." ); - } - - if( description == FML_DATA_DESCRIPTION_DOK_ARRAY ) - { - delete parameter->dataDescription; - parameter->dataDescription = new DokArrayDataDescription(); - return session->getLastError(); - } - else if( description == FML_DATA_DESCRIPTION_DENSE_ARRAY ) - { - delete parameter->dataDescription; - parameter->dataDescription = new DenseArrayDataDescription(); - return session->getLastError(); - } - else - { - return session->setError( FML_ERR_UNSUPPORTED, objectHandle, "Unsupported/invalid data description." ); - } - } - - return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator." ); -} - - -FieldmlDataDescriptionType Fieldml_GetParameterDataDescription( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_DATA_DESCRIPTION_UNKNOWN; - } - - ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); - if( parameter != NULL ) - { - return parameter->dataDescription->descriptionType; - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator." ); - return FML_DATA_DESCRIPTION_UNKNOWN; -} - - -FmlErrorNumber Fieldml_SetDataSource( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle dataSource ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - FieldmlObject *object = getObject( session, objectHandle ); - if( object == NULL ) - { - return session->getLastError(); - } - - if( !checkLocal( session, objectHandle ) ) - { - return session->getLastError(); - } - if( !checkLocal( session, dataSource ) ) - { - return session->getLastError(); - } - if( Fieldml_GetObjectType( handle, dataSource ) != FHT_DATA_SOURCE ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, dataSource, "Must be a data source." ); - } - - ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); - if( parameter != NULL ) - { - if( parameter->dataDescription->descriptionType == FML_DATA_DESCRIPTION_DENSE_ARRAY ) - { - //TODO Check that the rank of the data source is equal to the number of dense indexes. - DenseArrayDataDescription *denseArray = (DenseArrayDataDescription*)parameter->dataDescription; - denseArray->dataSource = dataSource; - } - else if( parameter->dataDescription->descriptionType == FML_DATA_DESCRIPTION_DOK_ARRAY ) - { - //TODO Check that the rank of the data source is equal to the number of dense indexes plus one. - DokArrayDataDescription *dokArray = (DokArrayDataDescription*)parameter->dataDescription; - dokArray->valueSource = dataSource; - } - else - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must have a data description that uses a data source." ); - } - return session->getLastError(); - } - - if( object->objectType == FHT_ENSEMBLE_TYPE ) - { - EnsembleType *ensembleType = (EnsembleType*)object; - FieldmlEnsembleMembersType type = ensembleType->membersType; - - if( ( type != FML_ENSEMBLE_MEMBER_LIST_DATA ) && ( type != FML_ENSEMBLE_MEMBER_RANGE_DATA ) && ( type != FML_ENSEMBLE_MEMBER_STRIDE_RANGE_DATA ) ) - { - return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Ensemble type does not require a data source." ); - } - - ensembleType->dataSource = dataSource; - } - else if( object->objectType == FHT_MESH_TYPE ) - { - MeshType *meshType = (MeshType *)object; - return Fieldml_SetDataSource( handle, meshType->elementsType, dataSource ); - } - else - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator, mesh type or ensemble type." ); - } - - return session->getLastError(); -} - - -FmlErrorNumber Fieldml_SetKeyDataSource( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle dataSource ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - if( !checkLocal( session, objectHandle ) ) - { - return session->getLastError(); - } - if( !checkLocal( session, dataSource ) ) - { - return session->getLastError(); - } - - if( Fieldml_GetObjectType( handle, dataSource ) != FHT_DATA_SOURCE ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, dataSource, "Must be a data source." ); - } - - ArrayDataSource *source = getArrayDataSource( session, dataSource ); - if( source == NULL ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, dataSource, "Must be an array data source." ); - } - else if( source->rank != 2 ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, dataSource, "Key data source must be rank 2." ); - } - - ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); - if( parameter != NULL ) - { - if( parameter->dataDescription->descriptionType == FML_DATA_DESCRIPTION_DOK_ARRAY ) - { - DokArrayDataDescription *dokArray = (DokArrayDataDescription*)parameter->dataDescription; - dokArray->keySource = dataSource; - } - else - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must have dictionary-of-keys data description." ); - } - return session->getLastError(); - } - - return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator." ); -} - - -FmlErrorNumber Fieldml_AddDenseIndexEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle indexHandle, FmlObjectHandle orderHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - FieldmlObject *object = getObject( session, objectHandle ); - if( object == NULL ) - { - return session->getLastError(); - } - - if( !checkLocal( session, objectHandle ) ) - { - return session->getLastError(); - } - if( !checkLocal( session, indexHandle ) ) - { - return session->getLastError(); - } - if( !checkLocal( session, orderHandle ) ) - { - return session->getLastError(); - } - - if( !checkIsEvaluatorType( session, indexHandle, false, true, false ) ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, indexHandle, "Must be an ensemble-valued evaluator to be used for ordering." ); - } - - if( orderHandle != FML_INVALID_HANDLE ) - { - if( Fieldml_GetObjectType( handle, orderHandle ) != FHT_DATA_SOURCE ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_4, orderHandle, "Must be a data source to be used for ordering." ); - } - - ArrayDataSource *orderSource = getArrayDataSource( session, orderHandle ); - if( orderSource == NULL ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_4, orderHandle, "Must be an array data source to be used for ordering." ); - } - else if( orderSource->rank != 1 ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_4, orderHandle, "Must be a rank 1 array data source to be used for ordering." ); - } - } - - if( !checkCyclicDependency( session, objectHandle, indexHandle ) ) - { - return session->getLastError(); - } - - ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); - if( parameter != NULL ) - { - FmlErrorNumber error = parameter->dataDescription->addIndexEvaluator( false, indexHandle, orderHandle ); - return session->setError( error, objectHandle, "Cannot set dense index evaluator." ); - } - - return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot add dense index evaluator. Must be a parameter evaluator." ); -} - - -FmlErrorNumber Fieldml_AddSparseIndexEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle indexHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - if( !checkLocal( session, objectHandle ) ) - { - return session->getLastError(); - } - if( !checkLocal( session, indexHandle ) ) - { - return session->getLastError(); - } - - if( !checkIsEvaluatorType( session, indexHandle, false, true, false ) ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, indexHandle, "Must be an ensemble-valued evaluator to be used for an index evaluator." ); - } - - if( !checkCyclicDependency( session, objectHandle, indexHandle ) ) - { - return session->getLastError(); - } - - ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); - if( parameter != NULL ) - { - FmlErrorNumber error = parameter->dataDescription->addIndexEvaluator( true, indexHandle, FML_INVALID_HANDLE ); - return session->setError( error, objectHandle, "Cannot set sparse index evaluator." ); - } - - return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot add sparse index evaluator. Must be a parameter evaluator." ); -} - - -int Fieldml_GetParameterIndexCount( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlBoolean isSparse ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); - if( parameter != NULL ) - { - int count = parameter->dataDescription->getIndexCount( isSparse != 0 ); - if( count == -1 ) - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get parameter index count." ); - } - - return count; - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator." ); - return -1; -} - - -FmlObjectHandle Fieldml_GetParameterIndexEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, int index, FmlBoolean isSparse ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); - if( parameter != NULL ) - { - FmlObjectHandle evaluator; - FmlErrorNumber error = parameter->dataDescription->getIndexEvaluator( index-1, isSparse != 0, evaluator ); - session->setError( error, objectHandle, "Cannot get parameter index evaluator." ); - - return evaluator; - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator." ); - return FML_INVALID_HANDLE; -} - - -FmlObjectHandle Fieldml_CreatePiecewiseEvaluator( FmlSessionHandle handle, const char * name, FmlObjectHandle valueType ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create piecewise evaluator. Invalid name." ); - return FML_INVALID_HANDLE; - } - - if( !checkLocal( session, valueType ) ) - { - return session->getLastError(); - } - - if( !checkIsValueType( session, valueType, true, true, false, true ) ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, valueType, "Invalid type for piecewise evaluator." ); - return FML_INVALID_HANDLE; - } - - PiecewiseEvaluator *piecewiseEvaluator = new PiecewiseEvaluator( name, valueType, false ); - - session->setError( FML_ERR_NO_ERROR, "" ); - return addObject( session, piecewiseEvaluator ); -} - - -FmlObjectHandle Fieldml_CreateAggregateEvaluator( FmlSessionHandle handle, const char * name, FmlObjectHandle valueType ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create aggregate evaluator. Invalid name." ); - return FML_INVALID_HANDLE; - } - - if( !checkLocal( session, valueType ) ) - { - return session->getLastError(); - } - - if( !checkIsValueType( session, valueType, true, false, false, false ) ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, valueType, "Invalid type for aggregate evaluator." ); - return FML_INVALID_HANDLE; - } - - AggregateEvaluator *aggregateEvaluator = new AggregateEvaluator( name, valueType, false ); - - session->setError( FML_ERR_NO_ERROR, "" ); - return addObject( session, aggregateEvaluator ); -} - - -FmlErrorNumber Fieldml_SetDefaultEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle evaluator ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - if( !checkLocal( session, objectHandle ) ) - { - return session->getLastError(); - } - if( !checkLocal( session, evaluator ) ) - { - return session->getLastError(); - } - - if( Fieldml_GetObjectType( handle, objectHandle ) == FHT_AGGREGATE_EVALUATOR ) - { - if( !checkIsEvaluatorType( session, evaluator, true, false, false ) ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, evaluator, "Invalid type for aggregator delegate." ); - } - } - else if( !checkIsEvaluatorTypeCompatible( session, objectHandle, evaluator ) ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Incompatible type for delegate evaluator." ); - } - - SimpleMap *map = getEvaluatorMap( session, objectHandle ); - - if( map == NULL ) - { - return session->getLastError(); - } - - if( !checkCyclicDependency( session, objectHandle, evaluator ) ) - { - return session->getLastError(); - } - - map->setDefault( evaluator ); - return session->getLastError(); -} - - -FmlObjectHandle Fieldml_GetDefaultEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - SimpleMap *map = getEvaluatorMap( session, objectHandle ); - - if( map == NULL ) - { - return FML_INVALID_HANDLE; - } - - return map->getDefault(); -} - - -FmlErrorNumber Fieldml_SetEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlEnsembleValue element, FmlObjectHandle evaluator ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - if( !checkLocal( session, objectHandle ) ) - { - return session->getLastError(); - } - if( !checkLocal( session, evaluator ) ) - { - return session->getLastError(); - } - - if( Fieldml_GetObjectType( handle, objectHandle ) == FHT_AGGREGATE_EVALUATOR ) - { - if( !checkIsEvaluatorType( session, evaluator, true, false, false ) ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, evaluator, "Invalid type for aggregator delegate." ); - } - } - else if( !checkIsEvaluatorTypeCompatible( session, objectHandle, evaluator ) ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Incompatible type for delegate evaluator." ); - } - - SimpleMap *map = getEvaluatorMap( session, objectHandle ); - - if( map == NULL ) - { - return session->getLastError(); - } - - if( !checkCyclicDependency( session, objectHandle, evaluator ) ) - { - return session->getLastError(); - } - - map->set( element, evaluator ); - return session->getLastError(); -} - - -int Fieldml_GetEvaluatorCount( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - SimpleMap *map = getEvaluatorMap( session, objectHandle ); - - if( map == NULL ) - { - return -1; - } - - return map->size(); -} - - -FmlEnsembleValue Fieldml_GetEvaluatorElement( FmlSessionHandle handle, FmlObjectHandle objectHandle, int evaluatorIndex ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - SimpleMap *map = getEvaluatorMap( session, objectHandle ); - - if( map == NULL ) - { - return -1; - } - - return map->getKey( evaluatorIndex - 1 ); -} - - -FmlObjectHandle Fieldml_GetEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, int evaluatorIndex ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - SimpleMap *map = getEvaluatorMap( session, objectHandle ); - - if( map == NULL ) - { - return FML_INVALID_HANDLE; - } - - return map->getValue( evaluatorIndex - 1 ); -} - - -FmlObjectHandle Fieldml_GetElementEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlEnsembleValue elementNumber, FmlBoolean allowDefault ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - SimpleMap *map = getEvaluatorMap( session, objectHandle ); - - if( map == NULL ) - { - return FML_INVALID_HANDLE; - } - - return map->get( elementNumber, allowDefault == 1 ); -} - - -FmlObjectHandle Fieldml_CreateReferenceEvaluator( FmlSessionHandle handle, const char * name, FmlObjectHandle sourceEvaluator ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create reference evaluator. Invalid name." ); - return FML_INVALID_HANDLE; - } - - if( !checkLocal( session, sourceEvaluator ) ) - { - return session->getLastError(); - } - - FmlObjectHandle valueType = Fieldml_GetValueType( handle, sourceEvaluator ); - - ReferenceEvaluator *referenceEvaluator = new ReferenceEvaluator( name, sourceEvaluator, valueType, false ); - - session->setError( FML_ERR_NO_ERROR, "" ); - return addObject( session, referenceEvaluator ); -} - - -FmlObjectHandle Fieldml_GetReferenceSourceEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - ReferenceEvaluator *reference = ReferenceEvaluator::checkedCast( session, objectHandle ); - if( reference != NULL ) - { - return reference->sourceEvaluator; - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a reference evaluator." ); - return FML_INVALID_HANDLE; -} - - -int Fieldml_GetArgumentCount( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlBoolean isBound, FmlBoolean isUsed ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - vector args = getArgumentList( session, objectHandle, isBound != 0, isUsed != 0 ); - if( session->getLastError() != FML_ERR_NO_ERROR ) - { - return -1; - } - return args.size(); -} - - -FmlObjectHandle Fieldml_GetArgument( FmlSessionHandle handle, FmlObjectHandle objectHandle, int argumentIndex, FmlBoolean isBound, FmlBoolean isUsed ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - vector args = getArgumentList( session, objectHandle, isBound != 0, isUsed != 0 ); - if( session->getLastError() != FML_ERR_NO_ERROR ) - { - return FML_INVALID_HANDLE; - } - - if( ( argumentIndex < 1 ) || ( argumentIndex > (int)args.size() ) ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Invalid index number." ); - return FML_INVALID_HANDLE; - } - - return args.at( argumentIndex - 1 ); -} - - -FmlErrorNumber Fieldml_AddArgument( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle evaluatorHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - if( !checkLocal( session, objectHandle ) ) - { - return session->getLastError(); - } - if( !checkLocal( session, evaluatorHandle ) ) - { - return session->getLastError(); - } - - if( Fieldml_GetObjectType( handle, evaluatorHandle ) != FHT_ARGUMENT_EVALUATOR ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Wrong type evaluator for argument evaluator." ); - } - - ArgumentEvaluator *argumentEvaluator = ArgumentEvaluator::checkedCast( session, objectHandle ); - if( argumentEvaluator != NULL ) - { - argumentEvaluator->arguments.insert( evaluatorHandle ); - return session->getLastError(); - } - - ExternalEvaluator *externalEvaluator = ExternalEvaluator::checkedCast( session, objectHandle ); - if( externalEvaluator != NULL ) - { - externalEvaluator->arguments.insert( evaluatorHandle ); - return session->getLastError(); - } - - return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an argument evaluator or external evaluator." ); -} - - -int Fieldml_GetBindCount( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - SimpleMap *map = getBindMap( session, objectHandle ); - if( map == NULL ) - { - return -1; - } - - return map->size(); -} - - -FmlObjectHandle Fieldml_GetBindArgument( FmlSessionHandle handle, FmlObjectHandle objectHandle, int bindIndex ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - SimpleMap *map = getBindMap( session, objectHandle ); - if( map == NULL ) - { - return FML_INVALID_HANDLE; - } - - return map->getKey( bindIndex - 1 ); -} - - -FmlObjectHandle Fieldml_GetBindEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, int bindIndex ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - SimpleMap *map = getBindMap( session, objectHandle ); - if( map == NULL ) - { - return FML_INVALID_HANDLE; - } - - return map->getValue( bindIndex - 1 ); -} - - -FmlObjectHandle Fieldml_GetBindByArgument( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle argumentHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - SimpleMap *map = getBindMap( session, objectHandle ); - if( map == NULL ) - { - return FML_INVALID_HANDLE; - } - - return map->get( argumentHandle, false ); -} - - -FmlErrorNumber Fieldml_SetBind( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle argumentHandle, FmlObjectHandle sourceHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - if( !checkLocal( session, objectHandle ) ) - { - return session->getLastError(); - } - if( !checkLocal( session, argumentHandle ) ) - { - return session->getLastError(); - } - if( !checkLocal( session, sourceHandle ) ) - { - return session->getLastError(); - } - - if( !checkIsEvaluatorTypeCompatible( session, argumentHandle, sourceHandle ) ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Incompatible bind for " + string( Fieldml_GetObjectName( handle, argumentHandle ) ) ); - } - - SimpleMap *map = getBindMap( session, objectHandle ); - if( map == NULL ) - { - return session->getLastError(); - } - - if( !checkCyclicDependency( session, objectHandle, sourceHandle ) ) - { - return session->getLastError(); - } - - map->set( argumentHandle, sourceHandle ); - return session->getLastError(); -} - - - -int Fieldml_GetIndexEvaluatorCount( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - PiecewiseEvaluator *piecewise = PiecewiseEvaluator::checkedCast( session, objectHandle ); - if( piecewise != NULL ) - { - return 1; - } - - AggregateEvaluator *aggregate = AggregateEvaluator::checkedCast( session, objectHandle ); - if( aggregate != NULL ) - { - return 1; - } - - ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); - if( parameter != NULL ) - { - int denseCount = parameter->dataDescription->getIndexCount( false ); - int sparseCount = parameter->dataDescription->getIndexCount( true ); - - if( ( denseCount > -1 ) && ( sparseCount > -1 ) ) - { - return denseCount + sparseCount; - } - else if( denseCount > -1 ) - { - return denseCount; - } - else if( sparseCount > -1 ) - { - return sparseCount; - } - else - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get index evaluator count." ); - return -1; - } - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator." ); - return -1; -} - - -FmlErrorNumber Fieldml_SetIndexEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, int index, FmlObjectHandle evaluatorHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - if( !checkLocal( session, objectHandle ) ) - { - return session->getLastError(); - } - if( !checkLocal( session, evaluatorHandle ) ) - { - return session->getLastError(); - } - - if( !checkIsEvaluatorType( session, evaluatorHandle, false, true, false ) ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_4, evaluatorHandle, "Must be ensemble-valued to be used as an index evaluator." ); - } - - if( !checkCyclicDependency( session, objectHandle, evaluatorHandle ) ) - { - return session->getLastError(); - } - - PiecewiseEvaluator *piecewise = PiecewiseEvaluator::checkedCast( session, objectHandle ); - if( piecewise != NULL ) - { - if( index == 1 ) - { - piecewise->indexEvaluator = evaluatorHandle; - return session->getLastError(); - } - else - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Invalid index for piecewise index evaluator." ); - } - } - - AggregateEvaluator *aggregate = AggregateEvaluator::checkedCast( session, objectHandle ); - if( aggregate != NULL ) - { - if( index == 1 ) - { - aggregate->indexEvaluator = evaluatorHandle; - return session->getLastError(); - } - else - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Invalid index for aggregate index evaluator." ); - } - } - - ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); - if( parameter != NULL ) - { - FmlErrorNumber error = parameter->dataDescription->setIndexEvaluator( index-1, evaluatorHandle, FML_INVALID_HANDLE ); - return session->setError( error, objectHandle, "Cannot set index evaluator." ); - } - - return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be piecewise or aggregate to set an index evaluator." ); -} - - -FmlObjectHandle Fieldml_GetIndexEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, int indexNumber ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - if( indexNumber <= 0 ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Invalid index number." ); - return FML_INVALID_HANDLE; - } - - PiecewiseEvaluator *piecewise = PiecewiseEvaluator::checkedCast( session, objectHandle ); - if( piecewise != NULL ) - { - if( indexNumber == 1 ) - { - return piecewise->indexEvaluator; - } - - session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Invalid index number." ); - return FML_INVALID_HANDLE; - } - - AggregateEvaluator *aggregate = AggregateEvaluator::checkedCast( session, objectHandle ); - if( aggregate != NULL ) - { - if( indexNumber == 1 ) - { - return aggregate->indexEvaluator; - } - - session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Invalid index number." ); - return FML_INVALID_HANDLE; - } - - ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); - if( parameter != NULL ) - { - FmlObjectHandle evaluator; - FmlErrorNumber error = parameter->dataDescription->getIndexEvaluator( indexNumber-1, evaluator ); - session->setError( error, objectHandle, "Cannot get index evaluator." ); - - return evaluator; - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Much be an aggregate, piecewise or parameter evaluator." ); - return FML_INVALID_HANDLE; -} - - -FmlObjectHandle Fieldml_GetParameterIndexOrder( FmlSessionHandle handle, FmlObjectHandle objectHandle, int index ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); - if( parameter != NULL ) - { - FmlObjectHandle order; - FmlErrorNumber error = parameter->dataDescription->getIndexOrder( index-1, order ); - session->setError( error, objectHandle, "Cannot get index order." ); - - return order; - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator." ); - return FML_INVALID_HANDLE; -} - - -FmlObjectHandle Fieldml_CreateBooleanType( FmlSessionHandle handle, const char * name ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create boolean type. Invalid name." ); - return FML_INVALID_HANDLE; - } - - BooleanType *booleanType = new BooleanType( name, false ); - - session->setError( FML_ERR_NO_ERROR, "" ); - return addObject( session, booleanType ); -} - - -FmlObjectHandle Fieldml_CreateContinuousType( FmlSessionHandle handle, const char * name ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create continuous type. Invalid name." ); - return FML_INVALID_HANDLE; - } - - ContinuousType *continuousType = new ContinuousType( name, false ); - - session->setError( FML_ERR_NO_ERROR, "" ); - return addObject( session, continuousType ); -} - - -FmlObjectHandle Fieldml_CreateContinuousTypeComponents( FmlSessionHandle handle, FmlObjectHandle typeHandle, const char * name, const int count ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, typeHandle, "Cannot create components. Invalid name." ); - return FML_INVALID_HANDLE; - } - - if( !checkLocal( session, typeHandle ) ) - { - return session->getLastError(); - } - - FieldmlObject *object = getObject( session, typeHandle ); - if( object == NULL ) - { - return FML_INVALID_HANDLE; - } - - if( object->objectType != FHT_CONTINUOUS_TYPE ) - { - session->setError( FML_ERR_INVALID_OBJECT, typeHandle, "Cannot create components. Must be a continuous type." ); - return FML_INVALID_HANDLE; - } - - ContinuousType *type = (ContinuousType*)object; - if( type->componentType != FML_INVALID_HANDLE ) - { - session->setError( FML_ERR_INVALID_OBJECT, typeHandle, "Cannot create new components. Components have already been created." ); - return FML_INVALID_HANDLE; - } - - if( count < 1 ) - { - session->setError( FML_ERR_INVALID_PARAMETER_4, typeHandle, "Cannot create components. Invalid count." ); - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, typeHandle, "Cannot create components. Invalid name." ); - return FML_INVALID_HANDLE; - } - - string trueName = name; - - if( strncmp( name, "~.", 2 ) == 0 ) - { - trueName = type->name + ( name + 1 ); - } - - EnsembleType *ensembleType = new EnsembleType( trueName, true, false ); - FmlObjectHandle componentHandle = addObject( session, ensembleType ); - Fieldml_SetEnsembleMembersRange( handle, componentHandle, 1, count, 1 ); - - type->componentType = componentHandle; - - return componentHandle; -} - - -FmlObjectHandle Fieldml_CreateEnsembleType( FmlSessionHandle handle, const char * name ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create ensemble type. Invalid name." ); - return FML_INVALID_HANDLE; - } - - EnsembleType *ensembleType = new EnsembleType( name, false, false ); - - session->setError( FML_ERR_NO_ERROR, "" ); - return addObject( session, ensembleType ); -} - - -FmlObjectHandle Fieldml_CreateMeshType( FmlSessionHandle handle, const char * name ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create mesh type. Invalid name." ); - return FML_INVALID_HANDLE; - } - - MeshType *meshType = new MeshType( name, false ); - - session->setError( FML_ERR_NO_ERROR, "" ); - - return addObject( session, meshType ); -} - - -FmlObjectHandle Fieldml_CreateMeshElementsType( FmlSessionHandle handle, FmlObjectHandle meshHandle, const char * name ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, meshHandle, "Cannot create mesh elements. Invalid name." ); - return FML_INVALID_HANDLE; - } - - if( !checkLocal( session, meshHandle ) ) - { - return session->getLastError(); - } - - FieldmlObject *object = getObject( session, meshHandle ); - if( object == NULL ) - { - return FML_INVALID_HANDLE; - } - - if( object->objectType != FHT_MESH_TYPE ) - { - session->setError( FML_ERR_INVALID_OBJECT, meshHandle, "Cannot create mesh elements. Must be a mesh type." ); - return FML_INVALID_HANDLE; - } - - MeshType *meshType = (MeshType*)object; - - EnsembleType *ensembleType = new EnsembleType( meshType->name + "." + name, false, true ); - FmlObjectHandle elementsHandle = addObject( session, ensembleType ); - - meshType->elementsType = elementsHandle; - - return elementsHandle; -} - - -FmlObjectHandle Fieldml_CreateMeshChartType( FmlSessionHandle handle, FmlObjectHandle meshHandle, const char * name ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, meshHandle, "Cannot create mesh chart. Invalid name." ); - return FML_INVALID_HANDLE; - } - - if( !checkLocal( session, meshHandle ) ) - { - return session->getLastError(); - } - - FieldmlObject *object = getObject( session, meshHandle ); - if( object == NULL ) - { - return FML_INVALID_HANDLE; - } - - if( object->objectType != FHT_MESH_TYPE ) - { - session->setError( FML_ERR_INVALID_OBJECT, meshHandle, "Cannot create mesh chart. Must be a mesh type." ); - return FML_INVALID_HANDLE; - } - - MeshType *meshType = (MeshType*)object; - - ContinuousType *chartType = new ContinuousType( meshType->name + "." + name, true ); - FmlObjectHandle chartHandle = addObject( session, chartType ); - - meshType->chartType = chartHandle; - - return chartHandle; -} - - -FmlErrorNumber Fieldml_SetMeshShapes( FmlSessionHandle handle, FmlObjectHandle meshHandle, FmlObjectHandle shapesHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - if( !checkLocal( session, meshHandle ) ) - { - return session->getLastError(); - } - if( !checkLocal( session, shapesHandle ) ) - { - return session->getLastError(); - } - - if( !checkIsEvaluatorType( session, shapesHandle, false, false, true ) ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, shapesHandle, "Cannot set mesh shapes. Must be a boolean-valued evaluator." ); - } - - FieldmlObject *object = getObject( session, meshHandle ); - - if( object == NULL ) - { - } - else if( object->objectType == FHT_MESH_TYPE ) - { - MeshType *meshType = (MeshType *)object; - meshType->shapes = shapesHandle; - } - else - { - session->setError( FML_ERR_INVALID_OBJECT, meshHandle, "Cannot set mesh shapes. Must be a mesh type." ); - } - - return session->getLastError(); -} - - -FmlErrorNumber Fieldml_SetEnsembleMembersRange( FmlSessionHandle handle, FmlObjectHandle objectHandle, const FmlEnsembleValue minElement, const FmlEnsembleValue maxElement, const int stride ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - if( !checkLocal( session, objectHandle ) ) - { - return session->getLastError(); - } - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - return session->getLastError(); - } - - if( ( minElement < 0 ) || ( minElement > maxElement ) ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Cannot set ensemble members range. Invalid range." ); - } - - if( stride < 1 ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_5, objectHandle, "Cannot set ensemble members range. Invalid stride." ); - } - - if( object->objectType == FHT_ENSEMBLE_TYPE ) - { - EnsembleType *ensemble = (EnsembleType*)object; - - ensemble->membersType = FML_ENSEMBLE_MEMBER_RANGE; - ensemble->min = minElement; - ensemble->max = maxElement; - ensemble->stride = stride; - ensemble->count = ( ( maxElement - minElement ) / stride ) + 1; - - return session->getLastError(); - } - else if( object->objectType == FHT_MESH_TYPE ) - { - MeshType *meshType = (MeshType*)object; - return Fieldml_SetEnsembleMembersRange( handle, meshType->elementsType, minElement, maxElement, stride ); - } - - return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot set ensemble members range. Must be a mesh type or ensemble type." ); -} - - -int Fieldml_AddImportSource( FmlSessionHandle handle, const char * href, const char * regionName ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); - return -1; - } - - if( href == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot add import. Invalid href." ); - return -1; - } - if( regionName == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, "Cannot add import. Invalid region name." ); - return -1; - } - - FieldmlRegion *importedRegion = session->getRegion( href, regionName ); - if( importedRegion == NULL ) - { - importedRegion = session->addResourceRegion( href, regionName ); - if( importedRegion == NULL ) - { - //TODO Get a more descriptive reason. - session->setError( FML_ERR_READ_ERR, "Cannot add import." ); - return -1; - } - } - - int index = session->getRegionIndex( href, regionName ); - if( index < 0 ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, string( "Cannot get index for import " ) + string( href ) + "." ); - return -1; - } - - session->region->addImportSource( index, href, regionName ); - - return index + 1; -} - - -FmlObjectHandle Fieldml_AddImport( FmlSessionHandle handle, int importSourceIndex, const char * localName, const char * remoteName ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); - return FML_INVALID_HANDLE; - } - - if( localName == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, "Import has invalid local name." ); - return FML_INVALID_HANDLE; - } - if( remoteName == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_4, "Import has invalid remote name." ); - return FML_INVALID_HANDLE; - } - - FieldmlRegion *region = session->getRegion( importSourceIndex - 1 ); - if( region == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Invalid import source index." ); - return FML_INVALID_HANDLE; - } - - FmlObjectHandle remoteObject = region->getNamedObject( remoteName ); - FmlObjectHandle localObject = session->region->getNamedObject( localName ); - - if( remoteObject == FML_INVALID_HANDLE ) - { - session->setError( FML_ERR_INVALID_PARAMETER_4, string( "Invalid import. Unknown remote object " ) + remoteName + "." ); - } - else if( localObject != FML_INVALID_HANDLE ) - { - remoteObject = FML_INVALID_HANDLE; - session->setError( FML_ERR_INVALID_PARAMETER_3, string( "Invalid import. Local name " ) + string( localName ) + " already used." ); - } - else - { - session->region->addImport( importSourceIndex - 1, localName, remoteName, remoteObject ); - } - - return remoteObject; -} - - -int Fieldml_GetImportSourceCount( FmlSessionHandle handle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); - return -1; - } - - return session->region->getImportSourceCount(); -} - - -int Fieldml_GetImportCount( FmlSessionHandle handle, int importSourceIndex ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); - return -1; - } - - return session->region->getImportCount( importSourceIndex - 1 ); -} - - -int Fieldml_CopyImportSourceHref( FmlSessionHandle handle, int importSourceIndex, char * buffer, int bufferLength ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); - return -1; - } - - string href = session->region->getImportSourceHref( importSourceIndex - 1 ); - if( href == "" ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Invalid import source index." ); - return -1; - } - - return cappedCopy( href.c_str(), buffer, bufferLength ); -} - - -int Fieldml_CopyImportSourceRegionName( FmlSessionHandle handle, int importSourceIndex, char * buffer, int bufferLength ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); - return -1; - } - - string regionName = session->region->getImportSourceRegionName( importSourceIndex - 1 ); - if( regionName == "" ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Invalid import source index." ); - return -1; - } - - return cappedCopy( regionName.c_str(), buffer, bufferLength ); -} - - -int Fieldml_CopyImportLocalName( FmlSessionHandle handle, int importSourceIndex, int importIndex, char * buffer, int bufferLength ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); - return -1; - } - - string localName = session->region->getImportLocalName( importSourceIndex - 1, importIndex ); - if( localName == "" ) - { - //TODO Report exactly which parameter was bad - session->setError( FML_ERR_INVALID_PARAMETER_3, "Invalid import index or source index." ); - return -1; - } - - return cappedCopy( localName.c_str(), buffer, bufferLength ); -} - - -int Fieldml_CopyImportRemoteName( FmlSessionHandle handle, int importSourceIndex, int importIndex, char * buffer, int bufferLength ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); - return -1; - } - - string remoteName = session->region->getImportRemoteName( importSourceIndex - 1, importIndex ); - if( remoteName == "" ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, "Invalid import or import source index." ); - return -1; - } - - return cappedCopy( remoteName.c_str(), buffer, bufferLength ); -} - - -FmlObjectHandle Fieldml_GetImportObject( FmlSessionHandle handle, int importSourceIndex, int importIndex ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); - return FML_INVALID_HANDLE; - } - - return session->region->getImportObject( importSourceIndex - 1, importIndex ); -} - - -FmlObjectHandle Fieldml_CreateHrefDataResource( FmlSessionHandle handle, const char * name, const char * format, const char * href ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create href data resource. Invalid name." ); - return FML_INVALID_HANDLE; - } - if( href == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, "Cannot create href data resource. Invalid href." ); - return FML_INVALID_HANDLE; - } - if( format == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_4, "Cannot create href data resource. Invalid format." ); - return FML_INVALID_HANDLE; - } - - DataResource *dataResource = new DataResource( name, FML_DATA_RESOURCE_HREF, format, href ); - - session->setError( FML_ERR_NO_ERROR, "" ); - return addObject( session, dataResource ); -} - - -FmlObjectHandle Fieldml_CreateInlineDataResource( FmlSessionHandle handle, const char * name ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create inline data resource. Invalid name." ); - return FML_INVALID_HANDLE; - } - - DataResource *dataResource = new DataResource( name, FML_DATA_RESOURCE_INLINE, PLAIN_TEXT_NAME, "" ); - session->setError( FML_ERR_NO_ERROR, "" ); - return addObject( session, dataResource ); -} - - -FieldmlDataResourceType Fieldml_GetDataResourceType( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_DATA_RESOURCE_UNKNOWN; - } - - FieldmlObject *object = getObject( session, objectHandle ); - if( object->objectType != FHT_DATA_RESOURCE ) - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get data resource type. Must be a data resource." ); - return FML_DATA_RESOURCE_UNKNOWN; - } - - DataResource *resource = (DataResource*)object; - return resource->resourceType; -} - - -FmlErrorNumber Fieldml_AddInlineData( FmlSessionHandle handle, FmlObjectHandle objectHandle, const char * data, const int length ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - if( data == NULL ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Cannot add inline data. Invalid data." ); - } - - if( !checkLocal( session, objectHandle ) ) - { - return session->getLastError(); - } - - DataResource *resource = getDataResource( session, objectHandle ); - if( resource == NULL ) - { - return session->getLastError(); - } - if( resource->resourceType != FML_DATA_RESOURCE_INLINE ) - { - return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot add inline data. Must be inline data resource." ); - } - - resource->description = resource->description + string( data, length ); - - return session->getLastError(); -} - - -FmlErrorNumber Fieldml_SetInlineData( FmlSessionHandle handle, FmlObjectHandle objectHandle, const char * data, const int length ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - if( data == NULL ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, "Cannot set inline data. Invalid data." ); - } - - if( !checkLocal( session, objectHandle ) ) - { - return session->getLastError(); - } - - DataResource *resource = getDataResource( session, objectHandle ); - if( resource == NULL ) - { - return session->getLastError(); - } - if( resource->resourceType != FML_DATA_RESOURCE_INLINE ) - { - return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot set inline data. Must be inline data resource." ); - } - - resource->description = string( data, length ); - - return session->getLastError(); -} - - -int Fieldml_GetInlineDataLength( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - DataResource *resource = getDataResource( session, objectHandle ); - if( resource == NULL ) - { - return -1; - } - if( resource->resourceType != FML_DATA_RESOURCE_INLINE ) - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get inline data length. Must be inline data resource." ); - return -1; - } - - return resource->description.length(); -} - - -char * Fieldml_GetInlineData( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return NULL; - } - - DataResource *resource = getDataResource( session, objectHandle ); - if( resource == NULL ) - { - return NULL; - } - if( resource->resourceType != FML_DATA_RESOURCE_INLINE ) - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get inline data. Must be inline data resource." ); - return NULL; - } - - return cstrCopy( resource->description ); -} - - -int Fieldml_CopyInlineData( FmlSessionHandle handle, FmlObjectHandle objectHandle, char * buffer, int bufferLength, int offset ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - DataResource *resource = getDataResource( session, objectHandle ); - if( resource == NULL ) - { - return -1; - } - if( resource->resourceType != FML_DATA_RESOURCE_INLINE ) - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot copy inline data. Must be inline data resource." ); - return -1; - } - - if( offset >= (int)resource->description.length() ) - { - return 0; - } - - //This is probably not the best way to do this - return cappedCopy( resource->description.c_str() + offset, buffer, bufferLength ); -} - - -FieldmlDataSourceType Fieldml_GetDataSourceType( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_DATA_SOURCE_UNKNOWN; - } - - DataSource *dataSource = objectAsDataSource( session, objectHandle ); - if( dataSource == NULL ) - { - return FML_DATA_SOURCE_UNKNOWN; - } - - return dataSource->sourceType; -} - - -char * Fieldml_GetDataResourceHref( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return NULL; - } - - DataResource *dataResource = getDataResource( session, objectHandle ); - if( dataResource == NULL ) - { - return NULL; - } - - if( dataResource->resourceType == FML_DATA_RESOURCE_HREF ) - { - return cstrCopy( dataResource->description ); - } - else - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get data resource href. Must be href data resource." ); - return NULL; - } -} - - -int Fieldml_CopyDataResourceHref( FmlSessionHandle handle, FmlObjectHandle objectHandle, char * buffer, int bufferLength ) -{ - return cappedCopyAndFree( Fieldml_GetDataResourceHref( handle, objectHandle ), buffer, bufferLength ); -} - - -char * Fieldml_GetDataResourceFormat( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return NULL; - } - - DataResource *dataResource = getDataResource( session, objectHandle ); - if( dataResource == NULL ) - { - return NULL; - } - - return cstrCopy( dataResource->format ); -} - - -int Fieldml_CopyDataResourceFormat( FmlSessionHandle handle, FmlObjectHandle objectHandle, char * buffer, int bufferLength ) -{ - return cappedCopyAndFree( Fieldml_GetDataResourceFormat( handle, objectHandle ), buffer, bufferLength ); -} - - -FmlObjectHandle Fieldml_GetDataSource( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); - if( parameter != NULL ) - { - if( parameter->dataDescription->descriptionType == FML_DATA_DESCRIPTION_DENSE_ARRAY ) - { - DenseArrayDataDescription *denseArray = (DenseArrayDataDescription*)parameter->dataDescription; - return denseArray->dataSource; - } - else if( parameter->dataDescription->descriptionType == FML_DATA_DESCRIPTION_DOK_ARRAY ) - { - DokArrayDataDescription *dokArray = (DokArrayDataDescription*)parameter->dataDescription; - return dokArray->valueSource; - } - else - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get data source. Invalid data description." ); - return FML_INVALID_HANDLE; - } - } - - FieldmlObject *object = getObject( session, objectHandle ); - - if( object == NULL ) - { - //Error has already been set. - } - else if( object->objectType == FHT_ENSEMBLE_TYPE ) - { - EnsembleType *ensembleType = (EnsembleType*)object; - FieldmlEnsembleMembersType type = ensembleType->membersType; - - if( ( type != FML_ENSEMBLE_MEMBER_LIST_DATA ) && ( type != FML_ENSEMBLE_MEMBER_RANGE_DATA ) && ( type != FML_ENSEMBLE_MEMBER_STRIDE_RANGE_DATA ) ) - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get data source. Invalid member description." ); - return FML_INVALID_HANDLE; - } - - return ensembleType->dataSource; - } - else if( object->objectType == FHT_MESH_TYPE ) - { - MeshType *meshType = (MeshType *)object; - return Fieldml_GetDataSource( handle, meshType->elementsType ); - } - else - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get data source. Invalid object." ); - return FML_INVALID_HANDLE; - } - - return FML_INVALID_HANDLE; -} - - -FmlObjectHandle Fieldml_GetKeyDataSource( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); - if( parameter != NULL ) - { - if( parameter->dataDescription->descriptionType == FML_DATA_DESCRIPTION_DOK_ARRAY ) - { - DokArrayDataDescription *dokArray = (DokArrayDataDescription*)parameter->dataDescription; - return dokArray->keySource; - } - else - { - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get key data source. Invalid data description." ); - } - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get key data source. Invalid object." ); - return FML_INVALID_HANDLE; -} - - -int Fieldml_GetDataSourceCount( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - - DataResource *resource = getDataResource( session, objectHandle ); - if( resource == NULL ) - { - return -1; - } - - return resource->dataSources.size(); -} - - -FmlObjectHandle Fieldml_GetDataSourceByIndex( FmlSessionHandle handle, FmlObjectHandle objectHandle, int index ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - - DataResource *resource = getDataResource( session, objectHandle ); - if( resource == NULL ) - { - return FML_INVALID_HANDLE; - } - - if( ( index < 0 ) || ( (unsigned int)index >= resource->dataSources.size() ) ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Cannot get data source. Invalid index." ); - return FML_INVALID_HANDLE; - } - - return resource->dataSources[index]; -} - - -FmlObjectHandle Fieldml_GetDataSourceResource( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( session->region == NULL ) - { - session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); - return FML_INVALID_HANDLE; - } - - DataSource *source = objectAsDataSource( session, objectHandle ); - if( source == NULL ) - { - return FML_INVALID_HANDLE; - } - - if( source->resource == NULL ) - { - return FML_ERR_MISCONFIGURED_OBJECT; - } - - return session->region->getNamedObject( source->resource->name ); -} - - -char * Fieldml_GetArrayDataSourceLocation( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return NULL; - } - - ArrayDataSource *source = getArrayDataSource( session, objectHandle ); - if( source == NULL ) - { - return NULL; - } - - return cstrCopy( source->location ); -} - - -int Fieldml_CopyArrayDataSourceLocation( FmlSessionHandle handle, FmlObjectHandle objectHandle, char * buffer, int bufferLength ) -{ - return cappedCopyAndFree( Fieldml_GetArrayDataSourceLocation( handle, objectHandle ), buffer, bufferLength ); -} - - -int Fieldml_GetArrayDataSourceRank( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return -1; - } - - FieldmlObject *object = getObject( session, objectHandle ); - if( object == NULL ) - { - return -1; - } - if( object->objectType != FHT_DATA_SOURCE ) - { - session->setError( FML_ERR_INVALID_OBJECT, "Cannot get array data source rank. Must be a data source." ); - return -1; - } - - DataSource *source = (DataSource*)object; - if( source->sourceType == FML_DATA_SOURCE_ARRAY ) - { - ArrayDataSource *arraySource = (ArrayDataSource*)source; - return arraySource->rank; - } - - session->setError( FML_ERR_INVALID_OBJECT, "Cannot get array data source rank. Must be an array data source." ); - return -1; -} - - -FmlErrorNumber Fieldml_GetArrayDataSourceSizes( FmlSessionHandle handle, FmlObjectHandle objectHandle, int *sizes ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return session->getLastError(); - } - - ArrayDataSource *source = getArrayDataSource( session, objectHandle ); - if( source == NULL ) - { - return session->getLastError(); - } - - for( int i = 0; i < source->rank; i++ ) - { - sizes[i] = source->sizes[i]; - } - - return FML_ERR_NO_ERROR; -} - - -FmlErrorNumber Fieldml_SetArrayDataSourceSizes( FmlSessionHandle handle, FmlObjectHandle objectHandle, int *sizes ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return session->getLastError(); - } - - ArrayDataSource *source = getArrayDataSource( session, objectHandle ); - if( source == NULL ) - { - return session->getLastError(); - } - - for( int i = 0; i < source->rank; i++ ) - { - if( sizes[i] < 0 ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Cannot set array data sizes. Invalid size." ); - } - } - - source->sizes.clear(); - for( int i = 0; i < source->rank; i++ ) - { - source->sizes.push_back( sizes[i] ); - } - - return FML_ERR_NO_ERROR; -} - - -FmlErrorNumber Fieldml_GetArrayDataSourceRawSizes( FmlSessionHandle handle, FmlObjectHandle objectHandle, int *sizes ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return session->getLastError(); - } - - ArrayDataSource *source = getArrayDataSource( session, objectHandle ); - if( source == NULL ) - { - return session->getLastError(); - } - - for( int i = 0; i < source->rank; i++ ) - { - sizes[i] = source->rawSizes[i]; - } - - return FML_ERR_NO_ERROR; -} - - -FmlErrorNumber Fieldml_SetArrayDataSourceRawSizes( FmlSessionHandle handle, FmlObjectHandle objectHandle, int *sizes ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return session->getLastError(); - } - - ArrayDataSource *source = getArrayDataSource( session, objectHandle ); - if( source == NULL ) - { - return session->getLastError(); - } - - for( int i = 0; i < source->rank; i++ ) - { - if( sizes[i] <= 0 ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, "Cannot set array data raw size. Invalid size." ); - } - } - - source->rawSizes.clear(); - for( int i = 0; i < source->rank; i++ ) - { - source->rawSizes.push_back( sizes[i] ); - } - - return FML_ERR_NO_ERROR; -} - - -FmlErrorNumber Fieldml_GetArrayDataSourceOffsets( FmlSessionHandle handle, FmlObjectHandle objectHandle, int *offsets ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return session->getLastError(); - } - - ArrayDataSource *source = getArrayDataSource( session, objectHandle ); - if( source == NULL ) - { - return session->getLastError(); - } - - for( int i = 0; i < source->rank; i++ ) - { - offsets[i] = source->offsets[i]; - } - - return FML_ERR_NO_ERROR; -} - - -FmlErrorNumber Fieldml_SetArrayDataSourceOffsets( FmlSessionHandle handle, FmlObjectHandle objectHandle, int *offsets ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return session->getLastError(); - } - - ArrayDataSource *source = getArrayDataSource( session, objectHandle ); - if( source == NULL ) - { - return session->getLastError(); - } - - for( int i = 0; i < source->rank; i++ ) - { - if( offsets[i] < 0 ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_3, "Cannot set array data offset. Invalid offset." ); - } - } - - source->offsets.clear(); - for( int i = 0; i < source->rank; i++ ) - { - source->offsets.push_back( offsets[i] ); - } - - return FML_ERR_NO_ERROR; -} - - -FmlObjectHandle Fieldml_CreateArrayDataSource( FmlSessionHandle handle, const char * name, FmlObjectHandle resourceHandle, const char * location, int rank ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_ERR_UNKNOWN_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create array data source. Invalid name." ); - return FML_INVALID_HANDLE; - } - if( location == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_4, "Cannot create array data source. Invalid location." ); - return FML_INVALID_HANDLE; - } - - if( !checkLocal( session, resourceHandle ) ) - { - return session->getLastError(); - } - - if( rank <= 0 ) - { - return session->setError( FML_ERR_INVALID_PARAMETER_5, "Cannot create array data source. Invalid rank." ); - } - - FieldmlObject *object = getObject( session, resourceHandle ); - if( object == NULL ) - { - return session->getLastError(); - } - if( object->objectType != FHT_DATA_RESOURCE ) - { - return session->setError( FML_ERR_INVALID_OBJECT, resourceHandle, "Cannot create array data source. Must be a data resource." ); - } - - DataResource *dataResource = getDataResource( session, resourceHandle ); - - ArrayDataSource *source = new ArrayDataSource( name, dataResource, location, rank ); - - session->setError( FML_ERR_NO_ERROR, "" ); - FmlObjectHandle sourceHandle = addObject( session, source ); - - dataResource->dataSources.push_back( sourceHandle ); - - return sourceHandle; -} - - -int Fieldml_CreateConstantEvaluator( FmlSessionHandle handle, const char * name, const char * literal, FmlObjectHandle valueType ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return FML_INVALID_HANDLE; - } - if( name == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create constant evaluator. Invalid name." ); - return FML_INVALID_HANDLE; - } - if( literal == NULL ) - { - session->setError( FML_ERR_INVALID_PARAMETER_3, "Cannot create constant evaluator. Invalid value." ); - return FML_INVALID_HANDLE; - } - - if( !checkLocal( session, valueType ) ) - { - return session->getLastError(); - } - - if( !checkIsValueType( session, valueType, true, true, false, true ) ) - { - session->setError( FML_ERR_INVALID_PARAMETER_4, valueType, "Cannot create constant evaluator. Invalid type." ); - return FML_INVALID_HANDLE; - } - - ConstantEvaluator *evaluator = new ConstantEvaluator( name, literal, valueType ); - - session->setError( FML_ERR_NO_ERROR, "" ); - return addObject( session, evaluator ); -} - - -char * Fieldml_GetConstantEvaluatorValueString( FmlSessionHandle handle, FmlObjectHandle objectHandle ) -{ - FieldmlSession *session = FieldmlSession::handleToSession( handle ); - ERROR_AUTOSTACK( session ); - - if( session == NULL ) - { - return NULL; - } - - ConstantEvaluator *evaluator = ConstantEvaluator::checkedCast( session, objectHandle ); - if( evaluator != NULL ) - { - return cstrCopy( evaluator->valueString ); - } - - session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get constant evaluator value. Invalid object." ); - return NULL; -} - - -int Fieldml_CopyConstantEvaluatorValueString( FmlSessionHandle handle, FmlObjectHandle objectHandle, char * buffer, int bufferLength ) -{ - return cappedCopyAndFree( Fieldml_GetConstantEvaluatorValueString( handle, objectHandle ), buffer, bufferLength ); -} +/* \file + * $Id$ + * \author Caton Little + * \brief + * + * \section LICENSE + * + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is FieldML + * + * The Initial Developer of the Original Code is Auckland Uniservices Ltd, + * Auckland, New Zealand. Portions created by the Initial Developer are + * Copyright (C) 2010 the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + */ + +#include + +#include + +#include "String_InternalLibrary.h" + +#include "fieldml_api.h" +#include "FieldmlSession.h" +#include "ErrorContextAutostack.h" +#include "fieldml_structs.h" +#include "Evaluators.h" +#include "fieldml_write.h" +#include "string_const.h" +#include "Util.h" + +#include "FieldmlRegion.h" + +using namespace std; + +//======================================================================== +// +// Utility +// +// NOTE: A number of these methods are just wrappers around FieldmlSession +// methods, but which also set error codes. Methods such as FieldmlSession::getObject +// should not set error codes themselves, as failure is not necessarily an error. +// +//======================================================================== + +static FieldmlObject *getObject( FieldmlSession *session, FmlObjectHandle objectHandle ) +{ + ERROR_AUTOSTACK( session ); + + FieldmlObject *object = session->getObject( objectHandle ); + + if( object == NULL ) + { + session->setError( FML_ERR_UNKNOWN_OBJECT, "Invalid object handle." ); + } + + return object; +} + + +static bool checkLocal( FieldmlSession *session, FmlObjectHandle objectHandle ) +{ + ERROR_AUTOSTACK( session ); + + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region." ); + return false; + } + + if( objectHandle == FML_INVALID_HANDLE ) + { + //Nano-hack. Makes checking legitimate FML_INVALID_HANDLE parameters easier. + return true; + } + + if( !session->region->hasLocalObject( objectHandle, true, true ) ) + { + session->setError( FML_ERR_NONLOCAL_OBJECT, objectHandle, "Not a local object." ); + return false; + } + + return true; +} + + +static FmlObjectHandle addObject( FieldmlSession *session, FieldmlObject *object ) +{ + ERROR_AUTOSTACK( session ); + + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); + return FML_INVALID_HANDLE; + } + + FmlObjectHandle handle = session->region->getNamedObject( object->name.c_str() ); + + if( handle == FML_INVALID_HANDLE ) + { + FmlObjectHandle handle = session->objects.addObject( object ); + session->region->addLocalObject( handle ); + return handle; + } + + FieldmlObject *oldObject = session->objects.getObject( handle ); + + session->logError( "Handle collision. Cannot replace", object->name.c_str(), oldObject->name.c_str() ); + delete object; + + session->setError( FML_ERR_NAME_COLLISION, "There is already an object named " + object->name + " in this scope." ); + + return FML_INVALID_HANDLE; +} + + +static SimpleMap *getEvaluatorMap( FieldmlSession *session, FmlObjectHandle objectHandle ) +{ + ERROR_AUTOSTACK( session ); + + FieldmlObject *object = getObject( session, objectHandle ); + if( object == NULL ) + { + return NULL; + } + + AggregateEvaluator *aggregate = AggregateEvaluator::checkedCast( session, objectHandle ); + if( aggregate != NULL ) + { + return &aggregate->evaluators; + } + + PiecewiseEvaluator *piecewise = PiecewiseEvaluator::checkedCast( session, objectHandle ); + if( piecewise != NULL ) + { + return &piecewise->evaluators; + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must either be a Piecewise or Aggregate evaluator." ); + return NULL; +} + + +static SimpleMap *getBindMap( FieldmlSession *session, FmlObjectHandle objectHandle ) +{ + ERROR_AUTOSTACK( session ); + + FieldmlObject *object = getObject( session, objectHandle ); + if( object == NULL ) + { + return NULL; + } + + AggregateEvaluator *aggregate = AggregateEvaluator::checkedCast( session, objectHandle ); + if( aggregate != NULL ) + { + return &aggregate->binds; + } + + PiecewiseEvaluator *piecewise = PiecewiseEvaluator::checkedCast( session, objectHandle ); + if( piecewise != NULL ) + { + return &piecewise->binds; + } + + ReferenceEvaluator *reference = ReferenceEvaluator::checkedCast( session, objectHandle ); + if( reference != NULL ) + { + return &reference->binds; + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an Aggregate, Piecewise or Reference evaluator." ); + return NULL; +} + + +static vector getArgumentList( FieldmlSession *session, FmlObjectHandle objectHandle, bool isBound, bool isUsed ) +{ + vector args; + + ERROR_AUTOSTACK( session ); + + FieldmlObject *object = getObject( session, objectHandle ); + if( object == NULL ) + { + return args; + } + + Evaluator *evaluator = Evaluator::checkedCast( session, objectHandle ); + + if( evaluator == NULL ) + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get arguments. Must be an evalator." ); + return args; + } + + if ( isBound && !isUsed ) + { + //Always an empty set with the current algorithm, as it only tracks unbound or used arguments. + return args; + } + if( !isBound && !isUsed ) + { + //Always an empty set with the current algorithm, as it assumes that arguments of arguments are used. + return args; + } + + set unbound, used; + session->getArguments( objectHandle, unbound, used, false ); + + if( isBound && isUsed ) + { + for( set::const_iterator i = used.begin(); i != used.end(); i++ ) + { + // Performance wise, I am not sure I should remove all elems from + // unbound in used or using find as shown below. + if (unbound.end() == unbound.find(*i)) + args.push_back( *i ); + } + return args; + } + else //if( !isBound && isUsed ) + { + //In used, and in unbound. Unbound is always is a subset of used with the current algorithm. + for( set::const_iterator i = unbound.begin(); i != unbound.end(); i++ ) + { + args.push_back( *i ); + } + return args; + } +} + + +static bool checkCyclicDependency( FieldmlSession *session, FmlObjectHandle objectHandle, FmlObjectHandle objectDependancy ) +{ + ERROR_AUTOSTACK( session ); + + set delegates; + session->getDelegateEvaluators( objectDependancy, delegates ); + if( FmlUtil::contains( delegates, objectHandle ) ) + { + session->setError( FML_ERR_CYCLIC_DEPENDENCY, objectHandle, "Cyclic dependancy." ); + return false; + } + + return true; +} + + +static char* cstrCopy( const string &s ) +{ + return strdupS( s.c_str() ); +} + +static int cappedCopy( const char * source, char * buffer, int bufferLength ) +{ + if( ( bufferLength <= 1 ) || ( source == NULL ) ) + { + return 0; + } + + int length = strlen( source ); + + if( length >= bufferLength ) + { + length = ( bufferLength - 1 ); + } + + memcpy( buffer, source, length ); + buffer[length] = 0; + + return length; +} + + +static int cappedCopyAndFree( const char * source, char * buffer, int bufferLength ) +{ + int length = cappedCopy( source, buffer, bufferLength ); + free( (void*)source ); + return length; +} + + +static DataSource *objectAsDataSource( FieldmlSession *session, FmlObjectHandle objectHandle ) +{ + ERROR_AUTOSTACK( session ); + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + return NULL; + } + + if( object->objectType != FHT_DATA_SOURCE ) + { + session->setError( FML_ERR_INVALID_OBJECT, "Must be a data source." ); + return NULL; + } + + return (DataSource*)object; +} + + +static ArrayDataSource *getArrayDataSource( FieldmlSession *session, FmlObjectHandle objectHandle ) +{ + ERROR_AUTOSTACK( session ); + + DataSource *dataSource = objectAsDataSource( session, objectHandle ); + + if( dataSource == NULL ) + { + return NULL; + } + + if( dataSource->sourceType != FML_DATA_SOURCE_ARRAY ) + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an array data source." ); + return NULL; + } + + ArrayDataSource *arraySource = (ArrayDataSource*)dataSource; + return arraySource; +} + + +static DataResource *getDataResource( FieldmlSession *session, FmlObjectHandle objectHandle ) +{ + ERROR_AUTOSTACK( session ); + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + return NULL; + } + + if( object->objectType != FHT_DATA_RESOURCE ) + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a data resource." ); + return NULL; + } + + return (DataResource*)object; +} + + +static bool checkIsValueType( FieldmlSession *session, FmlObjectHandle objectHandle, bool allowContinuous, bool allowEnsemble, bool allowMesh, bool allowBoolean ) +{ + ERROR_AUTOSTACK( session ); + + FieldmlObject *object = getObject( session, objectHandle ); + if( object == NULL ) + { + return false; + } + + switch( object->objectType ) + { + case FHT_CONTINUOUS_TYPE: + return allowContinuous; + case FHT_ENSEMBLE_TYPE: + return allowEnsemble; + case FHT_MESH_TYPE: + return allowMesh; + case FHT_BOOLEAN_TYPE: + return allowBoolean; + default: + return false; + } +} + + +static bool checkIsEvaluatorType( FieldmlSession *session, FmlObjectHandle objectHandle, bool allowContinuous, bool allowEnsemble, bool allowBoolean ) +{ + ERROR_AUTOSTACK( session ); + + Evaluator *evaluator = Evaluator::checkedCast( session, objectHandle ); + if( evaluator == NULL ) + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Is not an evaluator." ); + return false; + } + + return checkIsValueType( session, evaluator->valueType, allowContinuous, allowEnsemble, false, allowBoolean ); +} + + +static bool checkIsTypeCompatible( FieldmlSession *session, FmlObjectHandle objectHandle1, FmlObjectHandle objectHandle2 ) +{ + ERROR_AUTOSTACK( session ); + + if( !checkIsValueType( session, objectHandle1, true, true, false, true ) ) + { + return false; + } + if( !checkIsValueType( session, objectHandle2, true, true, false, true ) ) + { + return false; + } + + FieldmlObject *object1 = getObject( session, objectHandle1 ); + FieldmlObject *object2 = getObject( session, objectHandle2 ); + + if( object1->objectType != object2->objectType ) + { + return false; + } + else if( object1->objectType == FHT_BOOLEAN_TYPE ) + { + return true; + } + else if( object1->objectType == FHT_ENSEMBLE_TYPE ) + { + return objectHandle1 == objectHandle2; + } + else if( object1->objectType == FHT_CONTINUOUS_TYPE ) + { + FmlObjectHandle component1 = Fieldml_GetTypeComponentEnsemble( session->getSessionHandle(), objectHandle1 ); + FmlObjectHandle component2 = Fieldml_GetTypeComponentEnsemble( session->getSessionHandle(), objectHandle2 ); + + if( ( component1 == FML_INVALID_HANDLE ) && ( component2 == FML_INVALID_HANDLE ) ) + { + return true; + } + else if( ( component1 == FML_INVALID_HANDLE ) || ( component2 == FML_INVALID_HANDLE ) ) + { + return false; + } + + return Fieldml_GetTypeComponentCount( session->getSessionHandle(), objectHandle1 ) == Fieldml_GetTypeComponentCount( session->getSessionHandle(), objectHandle2 ); + } + else + { + return false; + } +} + + +static bool checkIsEvaluatorTypeCompatible( FieldmlSession *session, FmlObjectHandle objectHandle1, FmlObjectHandle objectHandle2 ) +{ + ERROR_AUTOSTACK( session ); + + if( !checkIsEvaluatorType( session, objectHandle1, true, true, true ) ) + { + return false; + } + if( !checkIsEvaluatorType( session, objectHandle2, true, true, true ) ) + { + return false; + } + + FmlObjectHandle typeHandle1 = Fieldml_GetValueType( session->getSessionHandle(), objectHandle1 ); + FmlObjectHandle typeHandle2 = Fieldml_GetValueType( session->getSessionHandle(), objectHandle2 ); + + return checkIsTypeCompatible( session, typeHandle1, typeHandle2 ); +} + + +//======================================================================== +// +// API +// +//======================================================================== + +FmlSessionHandle Fieldml_CreateFromFile( const char * filename ) +{ + FieldmlSession *session = new FieldmlSession(); + ErrorContextAutostack bob( session, __FILE__, __LINE__, __ECA_FUNC__ ); + + if( filename == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_1, "Cannot create FieldML session. Invalid filename." ); + } + else + { + session->region = session->addResourceRegion( filename, "" ); + if( session->region == NULL ) + { + session->setError( FML_ERR_READ_ERR, "Cannot create FieldML session. Invalid document or read error." ); + } + else + { + session->region->setRoot( getDirectory( filename ) ); + session->region->finalize(); + } + } + + return session->getSessionHandle(); +} + + +FmlSessionHandle Fieldml_Create( const char * location, const char * name ) +{ + FieldmlSession *session = new FieldmlSession(); + ERROR_AUTOSTACK( session ); + + if( location == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_1, "Cannot create FieldML session. Invalid location." ); + } + else if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create FieldML session. Invalid name." ); + } + else + { + session->region = session->addNewRegion( location, name ); + } + + return session->getSessionHandle(); +} + + +FmlErrorNumber Fieldml_SetDebug( FmlSessionHandle handle, int debug ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + session->setDebug( debug ); + + return session->setError( FML_ERR_NO_ERROR, "" ); +} + + +FmlErrorNumber Fieldml_GetLastError( FmlSessionHandle handle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + return session->getLastError(); +} + + +FmlErrorNumber Fieldml_WriteFile( FmlSessionHandle handle, const char * filename ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + if( session->region == NULL ) + { + return session->setError( FML_ERR_INVALID_REGION, "Cannot write FieldML file. FieldML session has no region." ); + } + if( filename == NULL ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot write FieldML file. Invalid filename." ); + } + + session->setError( FML_ERR_NO_ERROR, "" ); + session->region->setRoot( getDirectory( filename ) ); + + return writeFieldmlFile( session, handle, filename ); +} + + +void Fieldml_Destroy( FmlSessionHandle handle ) +{ + FieldmlSession::removeSession( handle ); +} + + +char * Fieldml_GetRegionName( FmlSessionHandle handle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return NULL; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "Cannot get region name. FieldML session has no region." ); + return NULL; + } + + session->setError( FML_ERR_NO_ERROR, "" ); + return cstrCopy( session->region->getName() ); +} + + +FmlErrorNumber Fieldml_FreeString( char * string ) +{ + if( string != NULL ) + { + free( string ); + } + + return FML_ERR_NO_ERROR; +} + + +int Fieldml_CopyRegionName( FmlSessionHandle handle, char * buffer, int bufferLength ) +{ + return cappedCopyAndFree( Fieldml_GetRegionName( handle ), buffer, bufferLength ); +} + + +char * Fieldml_GetRegionRoot( FmlSessionHandle handle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return NULL; + } + + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "Cannot get region root. FieldML session has no region." ); + return NULL; + } + + session->setError( FML_ERR_NO_ERROR, "" ); + return cstrCopy( session->region->getRoot() ); +} + + +int Fieldml_CopyRegionRoot( FmlSessionHandle handle, char * buffer, int bufferLength ) +{ + return cappedCopyAndFree( Fieldml_GetRegionRoot( handle ), buffer, bufferLength ); +} + + +int Fieldml_GetErrorCount( FmlSessionHandle handle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + session->setError( FML_ERR_NO_ERROR, "" ); + return session->getErrorCount(); +} + + +char * Fieldml_GetError( FmlSessionHandle handle, int index ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return NULL; + } + + session->setError( FML_ERR_NO_ERROR, "" ); + return cstrCopy( session->getError( index - 1 ) ); +} + + +int Fieldml_CopyError( FmlSessionHandle handle, int errorIndex, char * buffer, int bufferLength ) +{ + return cappedCopyAndFree( Fieldml_GetError( handle, errorIndex ), buffer, bufferLength ); +} + + +FmlErrorNumber Fieldml_ClearErrors( FmlSessionHandle handle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + session->clearErrors(); + return session->setError( FML_ERR_NO_ERROR, "" ); +} + + +int Fieldml_GetTotalObjectCount( FmlSessionHandle handle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + session->setError( FML_ERR_NO_ERROR, "" ); + return session->objects.getCount(); +} + + +FmlObjectHandle Fieldml_GetObjectByIndex( FmlSessionHandle handle, const int objectIndex ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + session->setError( FML_ERR_NO_ERROR, "" ); + return session->objects.getObjectByIndex( objectIndex ); +} + + +int Fieldml_GetObjectCount( FmlSessionHandle handle, FieldmlHandleType type ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + session->setError( FML_ERR_NO_ERROR, "" ); + if( type == FHT_UNKNOWN ) + { + return -1; + } + + return session->objects.getCount( type ); +} + + +FmlObjectHandle Fieldml_GetObject( FmlSessionHandle handle, FieldmlHandleType objectType, int objectIndex ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + session->setError( FML_ERR_NO_ERROR, "" ); + + FmlObjectHandle object = session->objects.getObjectByIndex( objectIndex, objectType ); + if( object == FML_INVALID_HANDLE ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, "Cannot get object by type. Invalid index." ); + } + + return object; +} + + +FmlObjectHandle Fieldml_GetObjectByName( FmlSessionHandle handle, const char * name ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "Cannot get object by local name. FieldML session has no region." ); + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot get object by local name. Invalid name." ); + return FML_INVALID_HANDLE; + } + + FmlObjectHandle object = session->region->getNamedObject( name ); + + return object; +} + + +FmlObjectHandle Fieldml_GetObjectByDeclaredName( FmlSessionHandle handle, const char * name ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot get object by declared name. Invalid name." ); + return FML_INVALID_HANDLE; + } + + FmlObjectHandle object = session->objects.getObjectByName( name ); + + return object; +} + +FmlObjectHandle Fieldml_GetObjectByDeclaredNameAndHref(FmlSessionHandle handle, const char* name, const char* href) +{ + FieldmlSession* session = FieldmlSession::handleToSession(handle); + ERROR_AUTOSTACK(session); + + if (session == NULL) + return FML_INVALID_HANDLE; + + FieldmlRegion* region = session->getRegion(href); + if (region == NULL) + { + session->setError(FML_ERR_INVALID_PARAMETER_3, "Cannot get object by declared name and href. Corresponding href not found in model."); + return FML_INVALID_HANDLE; + } + + FmlObjectHandle result = region->getNamedObject(name); + if (result == FML_INVALID_HANDLE) + session->setError(FML_ERR_INVALID_PARAMETER_2, "Cannot get object by declared name and href. The specified name was not found in the region."); +} + +FieldmlHandleType Fieldml_GetObjectType( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FHT_UNKNOWN; + } + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + return FHT_UNKNOWN; + } + + return object->objectType; +} + + +FmlObjectHandle Fieldml_GetTypeComponentEnsemble( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + return FML_INVALID_HANDLE; + } + + if( object->objectType == FHT_CONTINUOUS_TYPE ) + { + ContinuousType *continuousType = (ContinuousType*)object; + return continuousType->componentType; + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get component ensemble. Must be a type with components." ); + return FML_INVALID_HANDLE; +} + + +int Fieldml_GetTypeComponentCount( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + FmlObjectHandle componentTypeHandle = Fieldml_GetTypeComponentEnsemble( handle, objectHandle ); + + if( componentTypeHandle == FML_INVALID_HANDLE ) + { + if( session->getLastError() == FML_ERR_NO_ERROR ) + { + return 1; + } + return -1; + } + + return Fieldml_GetMemberCount( handle, componentTypeHandle ); +} + + +int Fieldml_GetMemberCount( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + return -1; + } + + if( object->objectType == FHT_ENSEMBLE_TYPE ) + { + EnsembleType *ensembleType = (EnsembleType*)object; + return ensembleType->count; + } + else if( object->objectType == FHT_MESH_TYPE ) + { + MeshType *meshType = (MeshType*)object; + return Fieldml_GetMemberCount( handle, meshType->elementsType ); + } + + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get member count. Must be a type with members/elements." ); + return -1; +} + + +FmlEnsembleValue Fieldml_GetEnsembleMembersMin( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + return -1; + } + + if( object->objectType == FHT_ENSEMBLE_TYPE ) + { + EnsembleType *ensembleType = (EnsembleType*)object; + return ensembleType->min; + } + else if( object->objectType == FHT_MESH_TYPE ) + { + MeshType *meshType = (MeshType*)object; + return Fieldml_GetEnsembleMembersMin( handle, meshType->elementsType ); + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an ensemble or mesh type." ); + return -1; +} + + +FmlEnsembleValue Fieldml_GetEnsembleMembersMax( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + return -1; + } + + if( object->objectType == FHT_ENSEMBLE_TYPE ) + { + EnsembleType *ensembleType = (EnsembleType*)object; + return ensembleType->max; + } + else if( object->objectType == FHT_MESH_TYPE ) + { + MeshType *meshType = (MeshType*)object; + return Fieldml_GetEnsembleMembersMax( handle, meshType->elementsType ); + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an ensemble or mesh type." ); + return -1; +} + + +int Fieldml_GetEnsembleMembersStride( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + return -1; + } + + if( object->objectType == FHT_ENSEMBLE_TYPE ) + { + EnsembleType *ensembleType = (EnsembleType*)object; + return ensembleType->stride; + } + else if( object->objectType == FHT_MESH_TYPE ) + { + MeshType *meshType = (MeshType*)object; + return Fieldml_GetEnsembleMembersStride( handle, meshType->elementsType ); + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an ensemble or mesh type." ); + return -1; +} + + +FieldmlEnsembleMembersType Fieldml_GetEnsembleMembersType( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ENSEMBLE_MEMBER_UNKNOWN; + } + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + return FML_ENSEMBLE_MEMBER_UNKNOWN; + } + + if( object->objectType == FHT_ENSEMBLE_TYPE ) + { + EnsembleType *ensembleType = (EnsembleType*)object; + return ensembleType->membersType; + } + else if( object->objectType == FHT_MESH_TYPE ) + { + MeshType *meshType = (MeshType *)object; + return Fieldml_GetEnsembleMembersType( handle, meshType->elementsType ); + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an ensemble or mesh type." ); + return FML_ENSEMBLE_MEMBER_UNKNOWN; +} + + +FmlErrorNumber Fieldml_SetEnsembleMembersDataSource( FmlSessionHandle handle, FmlObjectHandle objectHandle, FieldmlEnsembleMembersType type, int count, FmlObjectHandle dataSourceHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + if( !checkLocal( session, objectHandle ) ) + { + return session->getLastError(); + } + + if( Fieldml_GetObjectType( handle, dataSourceHandle ) != FHT_DATA_SOURCE ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_5, dataSourceHandle, "Must be a data source to be used for member labels." ); + } + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + return session->getLastError(); + } + else if( object->objectType == FHT_ENSEMBLE_TYPE ) + { + EnsembleType *ensembleType = (EnsembleType*)object; + + if( ( type != FML_ENSEMBLE_MEMBER_LIST_DATA ) && ( type != FML_ENSEMBLE_MEMBER_RANGE_DATA ) && ( type != FML_ENSEMBLE_MEMBER_STRIDE_RANGE_DATA ) ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Has a member type which cannot be used with a data source." ); + } + + ensembleType->membersType = type; + ensembleType->count = count; + ensembleType->dataSource = dataSourceHandle; + return session->getLastError(); + } + else if( object->objectType == FHT_MESH_TYPE ) + { + MeshType *meshType = (MeshType *)object; + return Fieldml_SetEnsembleMembersDataSource( handle, meshType->elementsType, type, count, dataSourceHandle ); + } + + return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an ensemble or mesh type." ); +} + + +FmlBoolean Fieldml_IsEnsembleComponentType( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + return -1; + } + + if( object->objectType == FHT_ENSEMBLE_TYPE ) + { + EnsembleType *ensembleType = (EnsembleType*)object; + return ensembleType->isComponentEnsemble; + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an ensemble type." ); + return -1; +} + + +FmlObjectHandle Fieldml_GetMeshElementsType( FmlSessionHandle handle, FmlObjectHandle meshHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + FieldmlObject *object = getObject( session, meshHandle ); + + if( object == NULL ) + { + return FML_INVALID_HANDLE; + } + if( object->objectType == FHT_MESH_TYPE ) + { + MeshType *meshType = (MeshType *)object; + return meshType->elementsType; + } + + session->setError( FML_ERR_INVALID_OBJECT, meshHandle, "Must be a mesh type." ); + return FML_INVALID_HANDLE; +} + + +FmlObjectHandle Fieldml_GetMeshShapes( FmlSessionHandle handle, FmlObjectHandle meshHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + FieldmlObject *object = getObject( session, meshHandle ); + + if( object == NULL ) + { + return FML_INVALID_HANDLE; + } + if( object->objectType == FHT_MESH_TYPE ) + { + MeshType *meshType = (MeshType *)object; + return meshType->shapes; + } + + session->setError( FML_ERR_INVALID_OBJECT, meshHandle, "Must be a mesh type." ); + return FML_INVALID_HANDLE; +} + + +FmlObjectHandle Fieldml_GetMeshChartType( FmlSessionHandle handle, FmlObjectHandle meshHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + FieldmlObject *object = getObject( session, meshHandle ); + + if( object == NULL ) + { + return FML_INVALID_HANDLE; + } + if( object->objectType == FHT_MESH_TYPE ) + { + MeshType *meshType = (MeshType *)object; + return meshType->chartType; + } + + session->setError( FML_ERR_INVALID_OBJECT, meshHandle, "Must be a mesh type." ); + return FML_INVALID_HANDLE; +} + + +FmlObjectHandle Fieldml_GetMeshChartComponentType( FmlSessionHandle handle, FmlObjectHandle meshHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + FieldmlObject *object = getObject( session, meshHandle ); + + if( object == NULL ) + { + return FML_INVALID_HANDLE; + } + if( object->objectType == FHT_MESH_TYPE ) + { + MeshType *meshType = (MeshType *)object; + return Fieldml_GetTypeComponentEnsemble( handle, meshType->chartType ); + } + + session->setError( FML_ERR_INVALID_OBJECT, meshHandle, "Must be a mesh type." ); + return FML_INVALID_HANDLE; +} + + +FmlBoolean Fieldml_IsObjectLocal( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlBoolean isDeclaredOnly ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); + return 0; + } + + bool allowVirtual = ( isDeclaredOnly != 1 ); + bool allowImport = ( isDeclaredOnly != 1 ); + if( session->region->hasLocalObject( objectHandle, allowVirtual, allowImport ) ) + { + return 1; + } + else + { + return 0; + } +} + + +char * Fieldml_GetObjectName( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return NULL; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); + return NULL; + } + + string name = session->region->getObjectName( objectHandle ); + if( name == "" ) + { + return NULL; + } + + return cstrCopy( name.c_str() ); +} + + +int Fieldml_CopyObjectName( FmlSessionHandle handle, FmlObjectHandle objectHandle, char * buffer, int bufferLength ) +{ + return cappedCopyAndFree( Fieldml_GetObjectName( handle, objectHandle ), buffer, bufferLength ); +} + + +char * Fieldml_GetObjectDeclaredName( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return NULL; + } + + FieldmlObject *object = session->objects.getObject( objectHandle ); + if( object == NULL ) + { + return NULL; + } + + return cstrCopy( object->name.c_str() ); +} + +char* +Fieldml_GetObjectDeclaredHref(FmlSessionHandle handle, FmlObjectHandle objectHandle) +{ + FieldmlSession *session = FieldmlSession::handleToSession(handle); + ERROR_AUTOSTACK(session); + + if (session == NULL) + return NULL; + + FieldmlObject *object = session->objects.getObject(objectHandle); + if (object == NULL) + return NULL; + + return cstrCopy(object->region->getName().c_str()); +} + +int Fieldml_CopyObjectDeclaredName( FmlSessionHandle handle, FmlObjectHandle objectHandle, char * buffer, int bufferLength ) +{ + return cappedCopyAndFree( Fieldml_GetObjectDeclaredName( handle, objectHandle ), buffer, bufferLength ); +} + + +FmlErrorNumber Fieldml_SetObjectInt( FmlSessionHandle handle, FmlObjectHandle objectHandle, int value ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + return session->getLastError(); + } + + object->intValue = value; + return session->getLastError(); +} + + +int Fieldml_GetObjectInt( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return 0; + } + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + return 0; + } + + return object->intValue; +} + + +FmlObjectHandle Fieldml_GetValueType( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + Evaluator *evaluator = Evaluator::checkedCast( session, objectHandle ); + if( evaluator != NULL ) + { + return evaluator->valueType; + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an evaluator." ); + return FML_INVALID_HANDLE; +} + + +FmlObjectHandle Fieldml_CreateArgumentEvaluator( FmlSessionHandle handle, const char * name, FmlObjectHandle valueType ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Invalid argument evaluator name." ); + return FML_INVALID_HANDLE; + } + + if( !checkLocal( session, valueType ) ) + { + return session->getLastError(); + } + + if( !checkIsValueType( session, valueType, true, true, true, true ) ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, valueType, "Invalid value type for argument evaluator " + string( name ) ); + return FML_INVALID_HANDLE; + } + + //TODO Icky hack to auto-add mesh type subevaluators. Subevaluators need to either be first-class objects, or + //specified at bind-time. + if( Fieldml_GetObjectType( handle, valueType ) == FHT_MESH_TYPE ) + { + FmlObjectHandle chartType = Fieldml_GetMeshChartType( handle, valueType ); + FmlObjectHandle elementsType = Fieldml_GetMeshElementsType( handle, valueType ); + + string meshName = session->region->getObjectName( valueType ); + meshName += "."; + + string argumentName = name; + string chartComponentName = session->region->getObjectName( chartType ); + string elementsComponentName = session->region->getObjectName( elementsType ); + + string chartSuffix = "chart"; + if( chartComponentName.compare( 0, meshName.length(), meshName ) == 0 ) + { + chartSuffix = chartComponentName.substr( meshName.length(), chartComponentName.length() ); + } + string chartName = argumentName + "." + chartSuffix; + + if( Fieldml_GetObjectByName( handle, chartName.c_str() ) != FML_INVALID_HANDLE ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, valueType, "Cannot create mesh argument evaluator. " + chartName + " already exists." ); + return FML_INVALID_HANDLE; + } + + string elementsSuffix = "elements"; + if( elementsComponentName.compare( 0, meshName.length(), meshName ) == 0 ) + { + elementsSuffix = elementsComponentName.substr( meshName.length(), elementsComponentName.length() ); + } + string elementsName = argumentName + "." + elementsSuffix; + + if( Fieldml_GetObjectByName( handle, elementsName.c_str() ) != FML_INVALID_HANDLE ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, valueType, "Cannot create mesh argument evaluator. " + elementsName + " already exists." ); + return FML_INVALID_HANDLE; + } + + //Shouldn't need to check for name-collision, as we already have. + ArgumentEvaluator *chartEvaluator = new ArgumentEvaluator( chartName.c_str(), session->region, chartType, true ); + addObject( session, chartEvaluator ); + + ArgumentEvaluator *elementEvaluator = new ArgumentEvaluator( elementsName.c_str(), session->region, elementsType, true ); + addObject( session, elementEvaluator ); + } + + ArgumentEvaluator *argumentEvaluator = new ArgumentEvaluator( name, session->region, valueType, false ); + + session->setError( FML_ERR_NO_ERROR, "" ); + return addObject( session, argumentEvaluator ); +} + + +FmlObjectHandle Fieldml_CreateExternalEvaluator( FmlSessionHandle handle, const char * name, FmlObjectHandle valueType ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create external evaluator. Invalid name." ); + return FML_INVALID_HANDLE; + } + + if( !checkLocal( session, valueType ) ) + { + return session->getLastError(); + } + + if( !checkIsValueType( session, valueType, true, true, false, true ) ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, valueType, "Cannot create external evaluator of this type." ); + return FML_INVALID_HANDLE; + } + + ExternalEvaluator *externalEvaluator = new ExternalEvaluator( name, session->region, valueType, false ); + + session->setError( FML_ERR_NO_ERROR, "" ); + return addObject( session, externalEvaluator ); +} + + +FmlObjectHandle Fieldml_CreateParameterEvaluator( FmlSessionHandle handle, const char * name, FmlObjectHandle valueType ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create parameter evaluator. Invalid name." ); + return FML_INVALID_HANDLE; + } + + if( !checkLocal( session, valueType ) ) + { + return session->getLastError(); + } + + if( !checkIsValueType( session, valueType, true, true, false, true ) ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, valueType, "Cannot create parameter evaluator of this type." ); + return FML_INVALID_HANDLE; + } + + ParameterEvaluator *parameterEvaluator = new ParameterEvaluator( name, session->region, valueType, false ); + + session->setError( FML_ERR_NO_ERROR, "" ); + return addObject( session, parameterEvaluator ); +} + + +FmlErrorNumber Fieldml_SetParameterDataDescription( FmlSessionHandle handle, FmlObjectHandle objectHandle, FieldmlDataDescriptionType description ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + if( !checkLocal( session, objectHandle ) ) + { + return session->getLastError(); + } + + ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); + if( parameter != NULL ) + { + if( parameter->dataDescription->descriptionType != FML_DATA_DESCRIPTION_UNKNOWN ) + { + return session->setError( FML_ERR_ACCESS_VIOLATION, objectHandle, "Parameter evaluator already has a data description." ); + } + + if( description == FML_DATA_DESCRIPTION_DOK_ARRAY ) + { + delete parameter->dataDescription; + parameter->dataDescription = new DokArrayDataDescription(); + return session->getLastError(); + } + else if( description == FML_DATA_DESCRIPTION_DENSE_ARRAY ) + { + delete parameter->dataDescription; + parameter->dataDescription = new DenseArrayDataDescription(); + return session->getLastError(); + } + else + { + return session->setError( FML_ERR_UNSUPPORTED, objectHandle, "Unsupported/invalid data description." ); + } + } + + return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator." ); +} + + +FieldmlDataDescriptionType Fieldml_GetParameterDataDescription( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_DATA_DESCRIPTION_UNKNOWN; + } + + ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); + if( parameter != NULL ) + { + return parameter->dataDescription->descriptionType; + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator." ); + return FML_DATA_DESCRIPTION_UNKNOWN; +} + + +FmlErrorNumber Fieldml_SetDataSource( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle dataSource ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + FieldmlObject *object = getObject( session, objectHandle ); + if( object == NULL ) + { + return session->getLastError(); + } + + if( !checkLocal( session, objectHandle ) ) + { + return session->getLastError(); + } + if( !checkLocal( session, dataSource ) ) + { + return session->getLastError(); + } + if( Fieldml_GetObjectType( handle, dataSource ) != FHT_DATA_SOURCE ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, dataSource, "Must be a data source." ); + } + + ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); + if( parameter != NULL ) + { + if( parameter->dataDescription->descriptionType == FML_DATA_DESCRIPTION_DENSE_ARRAY ) + { + //TODO Check that the rank of the data source is equal to the number of dense indexes. + DenseArrayDataDescription *denseArray = (DenseArrayDataDescription*)parameter->dataDescription; + denseArray->dataSource = dataSource; + } + else if( parameter->dataDescription->descriptionType == FML_DATA_DESCRIPTION_DOK_ARRAY ) + { + //TODO Check that the rank of the data source is equal to the number of dense indexes plus one. + DokArrayDataDescription *dokArray = (DokArrayDataDescription*)parameter->dataDescription; + dokArray->valueSource = dataSource; + } + else + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must have a data description that uses a data source." ); + } + return session->getLastError(); + } + + if( object->objectType == FHT_ENSEMBLE_TYPE ) + { + EnsembleType *ensembleType = (EnsembleType*)object; + FieldmlEnsembleMembersType type = ensembleType->membersType; + + if( ( type != FML_ENSEMBLE_MEMBER_LIST_DATA ) && ( type != FML_ENSEMBLE_MEMBER_RANGE_DATA ) && ( type != FML_ENSEMBLE_MEMBER_STRIDE_RANGE_DATA ) ) + { + return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Ensemble type does not require a data source." ); + } + + ensembleType->dataSource = dataSource; + } + else if( object->objectType == FHT_MESH_TYPE ) + { + MeshType *meshType = (MeshType *)object; + return Fieldml_SetDataSource( handle, meshType->elementsType, dataSource ); + } + else + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator, mesh type or ensemble type." ); + } + + return session->getLastError(); +} + + +FmlErrorNumber Fieldml_SetKeyDataSource( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle dataSource ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + if( !checkLocal( session, objectHandle ) ) + { + return session->getLastError(); + } + if( !checkLocal( session, dataSource ) ) + { + return session->getLastError(); + } + + if( Fieldml_GetObjectType( handle, dataSource ) != FHT_DATA_SOURCE ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, dataSource, "Must be a data source." ); + } + + ArrayDataSource *source = getArrayDataSource( session, dataSource ); + if( source == NULL ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, dataSource, "Must be an array data source." ); + } + else if( source->rank != 2 ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, dataSource, "Key data source must be rank 2." ); + } + + ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); + if( parameter != NULL ) + { + if( parameter->dataDescription->descriptionType == FML_DATA_DESCRIPTION_DOK_ARRAY ) + { + DokArrayDataDescription *dokArray = (DokArrayDataDescription*)parameter->dataDescription; + dokArray->keySource = dataSource; + } + else + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must have dictionary-of-keys data description." ); + } + return session->getLastError(); + } + + return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator." ); +} + + +FmlErrorNumber Fieldml_AddDenseIndexEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle indexHandle, FmlObjectHandle orderHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + FieldmlObject *object = getObject( session, objectHandle ); + if( object == NULL ) + { + return session->getLastError(); + } + + if( !checkLocal( session, objectHandle ) ) + { + return session->getLastError(); + } + if( !checkLocal( session, indexHandle ) ) + { + return session->getLastError(); + } + if( !checkLocal( session, orderHandle ) ) + { + return session->getLastError(); + } + + if( !checkIsEvaluatorType( session, indexHandle, false, true, false ) ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, indexHandle, "Must be an ensemble-valued evaluator to be used for ordering." ); + } + + if( orderHandle != FML_INVALID_HANDLE ) + { + if( Fieldml_GetObjectType( handle, orderHandle ) != FHT_DATA_SOURCE ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_4, orderHandle, "Must be a data source to be used for ordering." ); + } + + ArrayDataSource *orderSource = getArrayDataSource( session, orderHandle ); + if( orderSource == NULL ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_4, orderHandle, "Must be an array data source to be used for ordering." ); + } + else if( orderSource->rank != 1 ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_4, orderHandle, "Must be a rank 1 array data source to be used for ordering." ); + } + } + + if( !checkCyclicDependency( session, objectHandle, indexHandle ) ) + { + return session->getLastError(); + } + + ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); + if( parameter != NULL ) + { + FmlErrorNumber error = parameter->dataDescription->addIndexEvaluator( false, indexHandle, orderHandle ); + return session->setError( error, objectHandle, "Cannot set dense index evaluator." ); + } + + return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot add dense index evaluator. Must be a parameter evaluator." ); +} + + +FmlErrorNumber Fieldml_AddSparseIndexEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle indexHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + if( !checkLocal( session, objectHandle ) ) + { + return session->getLastError(); + } + if( !checkLocal( session, indexHandle ) ) + { + return session->getLastError(); + } + + if( !checkIsEvaluatorType( session, indexHandle, false, true, false ) ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, indexHandle, "Must be an ensemble-valued evaluator to be used for an index evaluator." ); + } + + if( !checkCyclicDependency( session, objectHandle, indexHandle ) ) + { + return session->getLastError(); + } + + ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); + if( parameter != NULL ) + { + FmlErrorNumber error = parameter->dataDescription->addIndexEvaluator( true, indexHandle, FML_INVALID_HANDLE ); + return session->setError( error, objectHandle, "Cannot set sparse index evaluator." ); + } + + return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot add sparse index evaluator. Must be a parameter evaluator." ); +} + + +int Fieldml_GetParameterIndexCount( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlBoolean isSparse ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); + if( parameter != NULL ) + { + int count = parameter->dataDescription->getIndexCount( isSparse != 0 ); + if( count == -1 ) + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get parameter index count." ); + } + + return count; + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator." ); + return -1; +} + + +FmlObjectHandle Fieldml_GetParameterIndexEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, int index, FmlBoolean isSparse ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); + if( parameter != NULL ) + { + FmlObjectHandle evaluator; + FmlErrorNumber error = parameter->dataDescription->getIndexEvaluator( index-1, isSparse != 0, evaluator ); + session->setError( error, objectHandle, "Cannot get parameter index evaluator." ); + + return evaluator; + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator." ); + return FML_INVALID_HANDLE; +} + + +FmlObjectHandle Fieldml_CreatePiecewiseEvaluator( FmlSessionHandle handle, const char * name, FmlObjectHandle valueType ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create piecewise evaluator. Invalid name." ); + return FML_INVALID_HANDLE; + } + + if( !checkLocal( session, valueType ) ) + { + return session->getLastError(); + } + + if( !checkIsValueType( session, valueType, true, true, false, true ) ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, valueType, "Invalid type for piecewise evaluator." ); + return FML_INVALID_HANDLE; + } + + PiecewiseEvaluator *piecewiseEvaluator = new PiecewiseEvaluator( name, session->region, valueType, false ); + + session->setError( FML_ERR_NO_ERROR, "" ); + return addObject( session, piecewiseEvaluator ); +} + + +FmlObjectHandle Fieldml_CreateAggregateEvaluator( FmlSessionHandle handle, const char * name, FmlObjectHandle valueType ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create aggregate evaluator. Invalid name." ); + return FML_INVALID_HANDLE; + } + + if( !checkLocal( session, valueType ) ) + { + return session->getLastError(); + } + + if( !checkIsValueType( session, valueType, true, false, false, false ) ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, valueType, "Invalid type for aggregate evaluator." ); + return FML_INVALID_HANDLE; + } + + AggregateEvaluator *aggregateEvaluator = new AggregateEvaluator( name, session->region, valueType, false ); + + session->setError( FML_ERR_NO_ERROR, "" ); + return addObject( session, aggregateEvaluator ); +} + + +FmlErrorNumber Fieldml_SetDefaultEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle evaluator ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + if( !checkLocal( session, objectHandle ) ) + { + return session->getLastError(); + } + if( !checkLocal( session, evaluator ) ) + { + return session->getLastError(); + } + + if( Fieldml_GetObjectType( handle, objectHandle ) == FHT_AGGREGATE_EVALUATOR ) + { + if( !checkIsEvaluatorType( session, evaluator, true, false, false ) ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, evaluator, "Invalid type for aggregator delegate." ); + } + } + else if( !checkIsEvaluatorTypeCompatible( session, objectHandle, evaluator ) ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Incompatible type for delegate evaluator." ); + } + + SimpleMap *map = getEvaluatorMap( session, objectHandle ); + + if( map == NULL ) + { + return session->getLastError(); + } + + if( !checkCyclicDependency( session, objectHandle, evaluator ) ) + { + return session->getLastError(); + } + + map->setDefault( evaluator ); + return session->getLastError(); +} + + +FmlObjectHandle Fieldml_GetDefaultEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + SimpleMap *map = getEvaluatorMap( session, objectHandle ); + + if( map == NULL ) + { + return FML_INVALID_HANDLE; + } + + return map->getDefault(); +} + + +FmlErrorNumber Fieldml_SetEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlEnsembleValue element, FmlObjectHandle evaluator ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + if( !checkLocal( session, objectHandle ) ) + { + return session->getLastError(); + } + if( !checkLocal( session, evaluator ) ) + { + return session->getLastError(); + } + + if( Fieldml_GetObjectType( handle, objectHandle ) == FHT_AGGREGATE_EVALUATOR ) + { + if( !checkIsEvaluatorType( session, evaluator, true, false, false ) ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, evaluator, "Invalid type for aggregator delegate." ); + } + } + else if( !checkIsEvaluatorTypeCompatible( session, objectHandle, evaluator ) ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Incompatible type for delegate evaluator." ); + } + + SimpleMap *map = getEvaluatorMap( session, objectHandle ); + + if( map == NULL ) + { + return session->getLastError(); + } + + if( !checkCyclicDependency( session, objectHandle, evaluator ) ) + { + return session->getLastError(); + } + + map->set( element, evaluator ); + return session->getLastError(); +} + + +int Fieldml_GetEvaluatorCount( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + SimpleMap *map = getEvaluatorMap( session, objectHandle ); + + if( map == NULL ) + { + return -1; + } + + return map->size(); +} + + +FmlEnsembleValue Fieldml_GetEvaluatorElement( FmlSessionHandle handle, FmlObjectHandle objectHandle, int evaluatorIndex ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + SimpleMap *map = getEvaluatorMap( session, objectHandle ); + + if( map == NULL ) + { + return -1; + } + + return map->getKey( evaluatorIndex - 1 ); +} + + +FmlObjectHandle Fieldml_GetEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, int evaluatorIndex ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + SimpleMap *map = getEvaluatorMap( session, objectHandle ); + + if( map == NULL ) + { + return FML_INVALID_HANDLE; + } + + return map->getValue( evaluatorIndex - 1 ); +} + + +FmlObjectHandle Fieldml_GetElementEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlEnsembleValue elementNumber, FmlBoolean allowDefault ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + SimpleMap *map = getEvaluatorMap( session, objectHandle ); + + if( map == NULL ) + { + return FML_INVALID_HANDLE; + } + + return map->get( elementNumber, allowDefault == 1 ); +} + + +FmlObjectHandle Fieldml_CreateReferenceEvaluator( FmlSessionHandle handle, const char * name, FmlObjectHandle sourceEvaluator ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create reference evaluator. Invalid name." ); + return FML_INVALID_HANDLE; + } + + if( !checkLocal( session, sourceEvaluator ) ) + { + return session->getLastError(); + } + + FmlObjectHandle valueType = Fieldml_GetValueType( handle, sourceEvaluator ); + + ReferenceEvaluator *referenceEvaluator = new ReferenceEvaluator( name, session->region, sourceEvaluator, valueType, false ); + + session->setError( FML_ERR_NO_ERROR, "" ); + return addObject( session, referenceEvaluator ); +} + + +FmlObjectHandle Fieldml_GetReferenceSourceEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + ReferenceEvaluator *reference = ReferenceEvaluator::checkedCast( session, objectHandle ); + if( reference != NULL ) + { + return reference->sourceEvaluator; + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a reference evaluator." ); + return FML_INVALID_HANDLE; +} + + +int Fieldml_GetArgumentCount( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlBoolean isBound, FmlBoolean isUsed ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + vector args = getArgumentList( session, objectHandle, isBound != 0, isUsed != 0 ); + if( session->getLastError() != FML_ERR_NO_ERROR ) + { + return -1; + } + return args.size(); +} + + +FmlObjectHandle Fieldml_GetArgument( FmlSessionHandle handle, FmlObjectHandle objectHandle, int argumentIndex, FmlBoolean isBound, FmlBoolean isUsed ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + vector args = getArgumentList( session, objectHandle, isBound != 0, isUsed != 0 ); + if( session->getLastError() != FML_ERR_NO_ERROR ) + { + return FML_INVALID_HANDLE; + } + + if( ( argumentIndex < 1 ) || ( argumentIndex > (int)args.size() ) ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Invalid index number." ); + return FML_INVALID_HANDLE; + } + + return args.at( argumentIndex - 1 ); +} + + +FmlErrorNumber Fieldml_AddArgument( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle evaluatorHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + if( !checkLocal( session, objectHandle ) ) + { + return session->getLastError(); + } + if( !checkLocal( session, evaluatorHandle ) ) + { + return session->getLastError(); + } + + if( Fieldml_GetObjectType( handle, evaluatorHandle ) != FHT_ARGUMENT_EVALUATOR ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Wrong type evaluator for argument evaluator." ); + } + + ArgumentEvaluator *argumentEvaluator = ArgumentEvaluator::checkedCast( session, objectHandle ); + if( argumentEvaluator != NULL ) + { + argumentEvaluator->arguments.insert( evaluatorHandle ); + return session->getLastError(); + } + + ExternalEvaluator *externalEvaluator = ExternalEvaluator::checkedCast( session, objectHandle ); + if( externalEvaluator != NULL ) + { + externalEvaluator->arguments.insert( evaluatorHandle ); + return session->getLastError(); + } + + return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be an argument evaluator or external evaluator." ); +} + + +int Fieldml_GetBindCount( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + SimpleMap *map = getBindMap( session, objectHandle ); + if( map == NULL ) + { + return -1; + } + + return map->size(); +} + + +FmlObjectHandle Fieldml_GetBindArgument( FmlSessionHandle handle, FmlObjectHandle objectHandle, int bindIndex ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + SimpleMap *map = getBindMap( session, objectHandle ); + if( map == NULL ) + { + return FML_INVALID_HANDLE; + } + + return map->getKey( bindIndex - 1 ); +} + + +FmlObjectHandle Fieldml_GetBindEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, int bindIndex ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + SimpleMap *map = getBindMap( session, objectHandle ); + if( map == NULL ) + { + return FML_INVALID_HANDLE; + } + + return map->getValue( bindIndex - 1 ); +} + + +FmlObjectHandle Fieldml_GetBindByArgument( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle argumentHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + SimpleMap *map = getBindMap( session, objectHandle ); + if( map == NULL ) + { + return FML_INVALID_HANDLE; + } + + return map->get( argumentHandle, false ); +} + + +FmlErrorNumber Fieldml_SetBind( FmlSessionHandle handle, FmlObjectHandle objectHandle, FmlObjectHandle argumentHandle, FmlObjectHandle sourceHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + if( !checkLocal( session, objectHandle ) ) + { + return session->getLastError(); + } + if( !checkLocal( session, argumentHandle ) ) + { + return session->getLastError(); + } + if( !checkLocal( session, sourceHandle ) ) + { + return session->getLastError(); + } + + if( !checkIsEvaluatorTypeCompatible( session, argumentHandle, sourceHandle ) ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Incompatible bind for " + string( Fieldml_GetObjectName( handle, argumentHandle ) ) ); + } + + SimpleMap *map = getBindMap( session, objectHandle ); + if( map == NULL ) + { + return session->getLastError(); + } + + if( !checkCyclicDependency( session, objectHandle, sourceHandle ) ) + { + return session->getLastError(); + } + + map->set( argumentHandle, sourceHandle ); + return session->getLastError(); +} + + + +int Fieldml_GetIndexEvaluatorCount( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + PiecewiseEvaluator *piecewise = PiecewiseEvaluator::checkedCast( session, objectHandle ); + if( piecewise != NULL ) + { + return 1; + } + + AggregateEvaluator *aggregate = AggregateEvaluator::checkedCast( session, objectHandle ); + if( aggregate != NULL ) + { + return 1; + } + + ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); + if( parameter != NULL ) + { + int denseCount = parameter->dataDescription->getIndexCount( false ); + int sparseCount = parameter->dataDescription->getIndexCount( true ); + + if( ( denseCount > -1 ) && ( sparseCount > -1 ) ) + { + return denseCount + sparseCount; + } + else if( denseCount > -1 ) + { + return denseCount; + } + else if( sparseCount > -1 ) + { + return sparseCount; + } + else + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get index evaluator count." ); + return -1; + } + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator." ); + return -1; +} + + +FmlErrorNumber Fieldml_SetIndexEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, int index, FmlObjectHandle evaluatorHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + if( !checkLocal( session, objectHandle ) ) + { + return session->getLastError(); + } + if( !checkLocal( session, evaluatorHandle ) ) + { + return session->getLastError(); + } + + if( !checkIsEvaluatorType( session, evaluatorHandle, false, true, false ) ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_4, evaluatorHandle, "Must be ensemble-valued to be used as an index evaluator." ); + } + + if( !checkCyclicDependency( session, objectHandle, evaluatorHandle ) ) + { + return session->getLastError(); + } + + PiecewiseEvaluator *piecewise = PiecewiseEvaluator::checkedCast( session, objectHandle ); + if( piecewise != NULL ) + { + if( index == 1 ) + { + piecewise->indexEvaluator = evaluatorHandle; + return session->getLastError(); + } + else + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Invalid index for piecewise index evaluator." ); + } + } + + AggregateEvaluator *aggregate = AggregateEvaluator::checkedCast( session, objectHandle ); + if( aggregate != NULL ) + { + if( index == 1 ) + { + aggregate->indexEvaluator = evaluatorHandle; + return session->getLastError(); + } + else + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Invalid index for aggregate index evaluator." ); + } + } + + ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); + if( parameter != NULL ) + { + FmlErrorNumber error = parameter->dataDescription->setIndexEvaluator( index-1, evaluatorHandle, FML_INVALID_HANDLE ); + return session->setError( error, objectHandle, "Cannot set index evaluator." ); + } + + return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be piecewise or aggregate to set an index evaluator." ); +} + + +FmlObjectHandle Fieldml_GetIndexEvaluator( FmlSessionHandle handle, FmlObjectHandle objectHandle, int indexNumber ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + if( indexNumber <= 0 ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Invalid index number." ); + return FML_INVALID_HANDLE; + } + + PiecewiseEvaluator *piecewise = PiecewiseEvaluator::checkedCast( session, objectHandle ); + if( piecewise != NULL ) + { + if( indexNumber == 1 ) + { + return piecewise->indexEvaluator; + } + + session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Invalid index number." ); + return FML_INVALID_HANDLE; + } + + AggregateEvaluator *aggregate = AggregateEvaluator::checkedCast( session, objectHandle ); + if( aggregate != NULL ) + { + if( indexNumber == 1 ) + { + return aggregate->indexEvaluator; + } + + session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Invalid index number." ); + return FML_INVALID_HANDLE; + } + + ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); + if( parameter != NULL ) + { + FmlObjectHandle evaluator; + FmlErrorNumber error = parameter->dataDescription->getIndexEvaluator( indexNumber-1, evaluator ); + session->setError( error, objectHandle, "Cannot get index evaluator." ); + + return evaluator; + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Much be an aggregate, piecewise or parameter evaluator." ); + return FML_INVALID_HANDLE; +} + + +FmlObjectHandle Fieldml_GetParameterIndexOrder( FmlSessionHandle handle, FmlObjectHandle objectHandle, int index ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); + if( parameter != NULL ) + { + FmlObjectHandle order; + FmlErrorNumber error = parameter->dataDescription->getIndexOrder( index-1, order ); + session->setError( error, objectHandle, "Cannot get index order." ); + + return order; + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Must be a parameter evaluator." ); + return FML_INVALID_HANDLE; +} + + +FmlObjectHandle Fieldml_CreateBooleanType( FmlSessionHandle handle, const char * name ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create boolean type. Invalid name." ); + return FML_INVALID_HANDLE; + } + + BooleanType *booleanType = new BooleanType( name, session->region, false ); + + session->setError( FML_ERR_NO_ERROR, "" ); + return addObject( session, booleanType ); +} + + +FmlObjectHandle Fieldml_CreateContinuousType( FmlSessionHandle handle, const char * name ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create continuous type. Invalid name." ); + return FML_INVALID_HANDLE; + } + + ContinuousType *continuousType = new ContinuousType( name, session->region, false ); + + session->setError( FML_ERR_NO_ERROR, "" ); + return addObject( session, continuousType ); +} + + +FmlObjectHandle Fieldml_CreateContinuousTypeComponents( FmlSessionHandle handle, FmlObjectHandle typeHandle, const char * name, const int count ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, typeHandle, "Cannot create components. Invalid name." ); + return FML_INVALID_HANDLE; + } + + if( !checkLocal( session, typeHandle ) ) + { + return session->getLastError(); + } + + FieldmlObject *object = getObject( session, typeHandle ); + if( object == NULL ) + { + return FML_INVALID_HANDLE; + } + + if( object->objectType != FHT_CONTINUOUS_TYPE ) + { + session->setError( FML_ERR_INVALID_OBJECT, typeHandle, "Cannot create components. Must be a continuous type." ); + return FML_INVALID_HANDLE; + } + + ContinuousType *type = (ContinuousType*)object; + if( type->componentType != FML_INVALID_HANDLE ) + { + session->setError( FML_ERR_INVALID_OBJECT, typeHandle, "Cannot create new components. Components have already been created." ); + return FML_INVALID_HANDLE; + } + + if( count < 1 ) + { + session->setError( FML_ERR_INVALID_PARAMETER_4, typeHandle, "Cannot create components. Invalid count." ); + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, typeHandle, "Cannot create components. Invalid name." ); + return FML_INVALID_HANDLE; + } + + string trueName = name; + + if( strncmp( name, "~.", 2 ) == 0 ) + { + trueName = type->name + ( name + 1 ); + } + + EnsembleType *ensembleType = new EnsembleType( trueName, session->region, true, false ); + FmlObjectHandle componentHandle = addObject( session, ensembleType ); + Fieldml_SetEnsembleMembersRange( handle, componentHandle, 1, count, 1 ); + + type->componentType = componentHandle; + + return componentHandle; +} + + +FmlObjectHandle Fieldml_CreateEnsembleType( FmlSessionHandle handle, const char * name ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create ensemble type. Invalid name." ); + return FML_INVALID_HANDLE; + } + + EnsembleType *ensembleType = new EnsembleType( name, session->region, false, false ); + + session->setError( FML_ERR_NO_ERROR, "" ); + return addObject( session, ensembleType ); +} + + +FmlObjectHandle Fieldml_CreateMeshType( FmlSessionHandle handle, const char * name ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create mesh type. Invalid name." ); + return FML_INVALID_HANDLE; + } + + MeshType *meshType = new MeshType( name, session->region, false ); + + session->setError( FML_ERR_NO_ERROR, "" ); + + return addObject( session, meshType ); +} + + +FmlObjectHandle Fieldml_CreateMeshElementsType( FmlSessionHandle handle, FmlObjectHandle meshHandle, const char * name ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, meshHandle, "Cannot create mesh elements. Invalid name." ); + return FML_INVALID_HANDLE; + } + + if( !checkLocal( session, meshHandle ) ) + { + return session->getLastError(); + } + + FieldmlObject *object = getObject( session, meshHandle ); + if( object == NULL ) + { + return FML_INVALID_HANDLE; + } + + if( object->objectType != FHT_MESH_TYPE ) + { + session->setError( FML_ERR_INVALID_OBJECT, meshHandle, "Cannot create mesh elements. Must be a mesh type." ); + return FML_INVALID_HANDLE; + } + + MeshType *meshType = (MeshType*)object; + + EnsembleType *ensembleType = new EnsembleType( meshType->name + "." + name, session->region, false, true ); + FmlObjectHandle elementsHandle = addObject( session, ensembleType ); + + meshType->elementsType = elementsHandle; + + return elementsHandle; +} + + +FmlObjectHandle Fieldml_CreateMeshChartType( FmlSessionHandle handle, FmlObjectHandle meshHandle, const char * name ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, meshHandle, "Cannot create mesh chart. Invalid name." ); + return FML_INVALID_HANDLE; + } + + if( !checkLocal( session, meshHandle ) ) + { + return session->getLastError(); + } + + FieldmlObject *object = getObject( session, meshHandle ); + if( object == NULL ) + { + return FML_INVALID_HANDLE; + } + + if( object->objectType != FHT_MESH_TYPE ) + { + session->setError( FML_ERR_INVALID_OBJECT, meshHandle, "Cannot create mesh chart. Must be a mesh type." ); + return FML_INVALID_HANDLE; + } + + MeshType *meshType = (MeshType*)object; + + ContinuousType *chartType = new ContinuousType( meshType->name + "." + name, session->region, true ); + FmlObjectHandle chartHandle = addObject( session, chartType ); + + meshType->chartType = chartHandle; + + return chartHandle; +} + + +FmlErrorNumber Fieldml_SetMeshShapes( FmlSessionHandle handle, FmlObjectHandle meshHandle, FmlObjectHandle shapesHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + if( !checkLocal( session, meshHandle ) ) + { + return session->getLastError(); + } + if( !checkLocal( session, shapesHandle ) ) + { + return session->getLastError(); + } + + if( !checkIsEvaluatorType( session, shapesHandle, false, false, true ) ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, shapesHandle, "Cannot set mesh shapes. Must be a boolean-valued evaluator." ); + } + + FieldmlObject *object = getObject( session, meshHandle ); + + if( object == NULL ) + { + } + else if( object->objectType == FHT_MESH_TYPE ) + { + MeshType *meshType = (MeshType *)object; + meshType->shapes = shapesHandle; + } + else + { + session->setError( FML_ERR_INVALID_OBJECT, meshHandle, "Cannot set mesh shapes. Must be a mesh type." ); + } + + return session->getLastError(); +} + + +FmlErrorNumber Fieldml_SetEnsembleMembersRange( FmlSessionHandle handle, FmlObjectHandle objectHandle, const FmlEnsembleValue minElement, const FmlEnsembleValue maxElement, const int stride ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + if( !checkLocal( session, objectHandle ) ) + { + return session->getLastError(); + } + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + return session->getLastError(); + } + + if( ( minElement < 0 ) || ( minElement > maxElement ) ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Cannot set ensemble members range. Invalid range." ); + } + + if( stride < 1 ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_5, objectHandle, "Cannot set ensemble members range. Invalid stride." ); + } + + if( object->objectType == FHT_ENSEMBLE_TYPE ) + { + EnsembleType *ensemble = (EnsembleType*)object; + + ensemble->membersType = FML_ENSEMBLE_MEMBER_RANGE; + ensemble->min = minElement; + ensemble->max = maxElement; + ensemble->stride = stride; + ensemble->count = ( ( maxElement - minElement ) / stride ) + 1; + + return session->getLastError(); + } + else if( object->objectType == FHT_MESH_TYPE ) + { + MeshType *meshType = (MeshType*)object; + return Fieldml_SetEnsembleMembersRange( handle, meshType->elementsType, minElement, maxElement, stride ); + } + + return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot set ensemble members range. Must be a mesh type or ensemble type." ); +} + + +int Fieldml_AddImportSource( FmlSessionHandle handle, const char * href, const char * regionName ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); + return -1; + } + + if( href == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot add import. Invalid href." ); + return -1; + } + if( regionName == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, "Cannot add import. Invalid region name." ); + return -1; + } + + FieldmlRegion *importedRegion = session->getRegion( href, regionName ); + if( importedRegion == NULL ) + { + importedRegion = session->addResourceRegion( href, regionName ); + if( importedRegion == NULL ) + { + //TODO Get a more descriptive reason. + session->setError( FML_ERR_READ_ERR, "Cannot add import." ); + return -1; + } + } + + int index = session->getRegionIndex( href, regionName ); + if( index < 0 ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, string( "Cannot get index for import " ) + string( href ) + "." ); + return -1; + } + + session->region->addImportSource( index, href, regionName ); + + return index + 1; +} + + +FmlObjectHandle Fieldml_AddImport( FmlSessionHandle handle, int importSourceIndex, const char * localName, const char * remoteName ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); + return FML_INVALID_HANDLE; + } + + if( localName == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, "Import has invalid local name." ); + return FML_INVALID_HANDLE; + } + if( remoteName == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_4, "Import has invalid remote name." ); + return FML_INVALID_HANDLE; + } + + FieldmlRegion *region = session->getRegion( importSourceIndex - 1 ); + if( region == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Invalid import source index." ); + return FML_INVALID_HANDLE; + } + + FmlObjectHandle remoteObject = region->getNamedObject( remoteName ); + FmlObjectHandle localObject = session->region->getNamedObject( localName ); + + if( remoteObject == FML_INVALID_HANDLE ) + { + session->setError( FML_ERR_INVALID_PARAMETER_4, string( "Invalid import. Unknown remote object " ) + remoteName + "." ); + } + else if( localObject != FML_INVALID_HANDLE ) + { + remoteObject = FML_INVALID_HANDLE; + session->setError( FML_ERR_INVALID_PARAMETER_3, string( "Invalid import. Local name " ) + string( localName ) + " already used." ); + } + else + { + session->region->addImport( importSourceIndex - 1, localName, remoteName, remoteObject ); + } + + return remoteObject; +} + + +int Fieldml_GetImportSourceCount( FmlSessionHandle handle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); + return -1; + } + + return session->region->getImportSourceCount(); +} + + +int Fieldml_GetImportCount( FmlSessionHandle handle, int importSourceIndex ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); + return -1; + } + + return session->region->getImportCount( importSourceIndex - 1 ); +} + + +int Fieldml_CopyImportSourceHref( FmlSessionHandle handle, int importSourceIndex, char * buffer, int bufferLength ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); + return -1; + } + + string href = session->region->getImportSourceHref( importSourceIndex - 1 ); + if( href == "" ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Invalid import source index." ); + return -1; + } + + return cappedCopy( href.c_str(), buffer, bufferLength ); +} + + +int Fieldml_CopyImportSourceRegionName( FmlSessionHandle handle, int importSourceIndex, char * buffer, int bufferLength ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); + return -1; + } + + string regionName = session->region->getImportSourceRegionName( importSourceIndex - 1 ); + if( regionName == "" ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Invalid import source index." ); + return -1; + } + + return cappedCopy( regionName.c_str(), buffer, bufferLength ); +} + + +int Fieldml_CopyImportLocalName( FmlSessionHandle handle, int importSourceIndex, int importIndex, char * buffer, int bufferLength ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); + return -1; + } + + string localName = session->region->getImportLocalName( importSourceIndex - 1, importIndex ); + if( localName == "" ) + { + //TODO Report exactly which parameter was bad + session->setError( FML_ERR_INVALID_PARAMETER_3, "Invalid import index or source index." ); + return -1; + } + + return cappedCopy( localName.c_str(), buffer, bufferLength ); +} + + +int Fieldml_CopyImportRemoteName( FmlSessionHandle handle, int importSourceIndex, int importIndex, char * buffer, int bufferLength ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); + return -1; + } + + string remoteName = session->region->getImportRemoteName( importSourceIndex - 1, importIndex ); + if( remoteName == "" ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, "Invalid import or import source index." ); + return -1; + } + + return cappedCopy( remoteName.c_str(), buffer, bufferLength ); +} + + +FmlObjectHandle Fieldml_GetImportObject( FmlSessionHandle handle, int importSourceIndex, int importIndex ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); + return FML_INVALID_HANDLE; + } + + return session->region->getImportObject( importSourceIndex - 1, importIndex ); +} + + +FmlObjectHandle Fieldml_CreateHrefDataResource( FmlSessionHandle handle, const char * name, const char * format, const char * href ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create href data resource. Invalid name." ); + return FML_INVALID_HANDLE; + } + if( href == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, "Cannot create href data resource. Invalid href." ); + return FML_INVALID_HANDLE; + } + if( format == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_4, "Cannot create href data resource. Invalid format." ); + return FML_INVALID_HANDLE; + } + + DataResource *dataResource = new DataResource( name, session->region, FML_DATA_RESOURCE_HREF, format, href ); + + session->setError( FML_ERR_NO_ERROR, "" ); + return addObject( session, dataResource ); +} + + +FmlObjectHandle Fieldml_CreateInlineDataResource( FmlSessionHandle handle, const char * name ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create inline data resource. Invalid name." ); + return FML_INVALID_HANDLE; + } + + DataResource *dataResource = new DataResource( name, session->region, FML_DATA_RESOURCE_INLINE, PLAIN_TEXT_NAME, "" ); + session->setError( FML_ERR_NO_ERROR, "" ); + return addObject( session, dataResource ); +} + + +FieldmlDataResourceType Fieldml_GetDataResourceType( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_DATA_RESOURCE_UNKNOWN; + } + + FieldmlObject *object = getObject( session, objectHandle ); + if( object->objectType != FHT_DATA_RESOURCE ) + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get data resource type. Must be a data resource." ); + return FML_DATA_RESOURCE_UNKNOWN; + } + + DataResource *resource = (DataResource*)object; + return resource->resourceType; +} + + +FmlErrorNumber Fieldml_AddInlineData( FmlSessionHandle handle, FmlObjectHandle objectHandle, const char * data, const int length ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + if( data == NULL ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Cannot add inline data. Invalid data." ); + } + + if( !checkLocal( session, objectHandle ) ) + { + return session->getLastError(); + } + + DataResource *resource = getDataResource( session, objectHandle ); + if( resource == NULL ) + { + return session->getLastError(); + } + if( resource->resourceType != FML_DATA_RESOURCE_INLINE ) + { + return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot add inline data. Must be inline data resource." ); + } + + resource->description = resource->description + string( data, length ); + + return session->getLastError(); +} + + +FmlErrorNumber Fieldml_SetInlineData( FmlSessionHandle handle, FmlObjectHandle objectHandle, const char * data, const int length ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + if( data == NULL ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, "Cannot set inline data. Invalid data." ); + } + + if( !checkLocal( session, objectHandle ) ) + { + return session->getLastError(); + } + + DataResource *resource = getDataResource( session, objectHandle ); + if( resource == NULL ) + { + return session->getLastError(); + } + if( resource->resourceType != FML_DATA_RESOURCE_INLINE ) + { + return session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot set inline data. Must be inline data resource." ); + } + + resource->description = string( data, length ); + + return session->getLastError(); +} + + +int Fieldml_GetInlineDataLength( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + DataResource *resource = getDataResource( session, objectHandle ); + if( resource == NULL ) + { + return -1; + } + if( resource->resourceType != FML_DATA_RESOURCE_INLINE ) + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get inline data length. Must be inline data resource." ); + return -1; + } + + return resource->description.length(); +} + + +char * Fieldml_GetInlineData( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return NULL; + } + + DataResource *resource = getDataResource( session, objectHandle ); + if( resource == NULL ) + { + return NULL; + } + if( resource->resourceType != FML_DATA_RESOURCE_INLINE ) + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get inline data. Must be inline data resource." ); + return NULL; + } + + return cstrCopy( resource->description ); +} + + +int Fieldml_CopyInlineData( FmlSessionHandle handle, FmlObjectHandle objectHandle, char * buffer, int bufferLength, int offset ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + DataResource *resource = getDataResource( session, objectHandle ); + if( resource == NULL ) + { + return -1; + } + if( resource->resourceType != FML_DATA_RESOURCE_INLINE ) + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot copy inline data. Must be inline data resource." ); + return -1; + } + + if( offset >= (int)resource->description.length() ) + { + return 0; + } + + //This is probably not the best way to do this + return cappedCopy( resource->description.c_str() + offset, buffer, bufferLength ); +} + + +FieldmlDataSourceType Fieldml_GetDataSourceType( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_DATA_SOURCE_UNKNOWN; + } + + DataSource *dataSource = objectAsDataSource( session, objectHandle ); + if( dataSource == NULL ) + { + return FML_DATA_SOURCE_UNKNOWN; + } + + return dataSource->sourceType; +} + + +char * Fieldml_GetDataResourceHref( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return NULL; + } + + DataResource *dataResource = getDataResource( session, objectHandle ); + if( dataResource == NULL ) + { + return NULL; + } + + if( dataResource->resourceType == FML_DATA_RESOURCE_HREF ) + { + return cstrCopy( dataResource->description ); + } + else + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get data resource href. Must be href data resource." ); + return NULL; + } +} + + +int Fieldml_CopyDataResourceHref( FmlSessionHandle handle, FmlObjectHandle objectHandle, char * buffer, int bufferLength ) +{ + return cappedCopyAndFree( Fieldml_GetDataResourceHref( handle, objectHandle ), buffer, bufferLength ); +} + + +char * Fieldml_GetDataResourceFormat( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return NULL; + } + + DataResource *dataResource = getDataResource( session, objectHandle ); + if( dataResource == NULL ) + { + return NULL; + } + + return cstrCopy( dataResource->format ); +} + + +int Fieldml_CopyDataResourceFormat( FmlSessionHandle handle, FmlObjectHandle objectHandle, char * buffer, int bufferLength ) +{ + return cappedCopyAndFree( Fieldml_GetDataResourceFormat( handle, objectHandle ), buffer, bufferLength ); +} + + +FmlObjectHandle Fieldml_GetDataSource( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); + if( parameter != NULL ) + { + if( parameter->dataDescription->descriptionType == FML_DATA_DESCRIPTION_DENSE_ARRAY ) + { + DenseArrayDataDescription *denseArray = (DenseArrayDataDescription*)parameter->dataDescription; + return denseArray->dataSource; + } + else if( parameter->dataDescription->descriptionType == FML_DATA_DESCRIPTION_DOK_ARRAY ) + { + DokArrayDataDescription *dokArray = (DokArrayDataDescription*)parameter->dataDescription; + return dokArray->valueSource; + } + else + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get data source. Invalid data description." ); + return FML_INVALID_HANDLE; + } + } + + FieldmlObject *object = getObject( session, objectHandle ); + + if( object == NULL ) + { + //Error has already been set. + } + else if( object->objectType == FHT_ENSEMBLE_TYPE ) + { + EnsembleType *ensembleType = (EnsembleType*)object; + FieldmlEnsembleMembersType type = ensembleType->membersType; + + if( ( type != FML_ENSEMBLE_MEMBER_LIST_DATA ) && ( type != FML_ENSEMBLE_MEMBER_RANGE_DATA ) && ( type != FML_ENSEMBLE_MEMBER_STRIDE_RANGE_DATA ) ) + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get data source. Invalid member description." ); + return FML_INVALID_HANDLE; + } + + return ensembleType->dataSource; + } + else if( object->objectType == FHT_MESH_TYPE ) + { + MeshType *meshType = (MeshType *)object; + return Fieldml_GetDataSource( handle, meshType->elementsType ); + } + else + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get data source. Invalid object." ); + return FML_INVALID_HANDLE; + } + + return FML_INVALID_HANDLE; +} + + +FmlObjectHandle Fieldml_GetKeyDataSource( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + ParameterEvaluator *parameter = ParameterEvaluator::checkedCast( session, objectHandle ); + if( parameter != NULL ) + { + if( parameter->dataDescription->descriptionType == FML_DATA_DESCRIPTION_DOK_ARRAY ) + { + DokArrayDataDescription *dokArray = (DokArrayDataDescription*)parameter->dataDescription; + return dokArray->keySource; + } + else + { + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get key data source. Invalid data description." ); + } + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get key data source. Invalid object." ); + return FML_INVALID_HANDLE; +} + + +int Fieldml_GetDataSourceCount( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + + DataResource *resource = getDataResource( session, objectHandle ); + if( resource == NULL ) + { + return -1; + } + + return resource->dataSources.size(); +} + + +FmlObjectHandle Fieldml_GetDataSourceByIndex( FmlSessionHandle handle, FmlObjectHandle objectHandle, int index ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + + DataResource *resource = getDataResource( session, objectHandle ); + if( resource == NULL ) + { + return FML_INVALID_HANDLE; + } + + if( ( index < 0 ) || ( (unsigned int)index >= resource->dataSources.size() ) ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Cannot get data source. Invalid index." ); + return FML_INVALID_HANDLE; + } + + return resource->dataSources[index]; +} + + +FmlObjectHandle Fieldml_GetDataSourceResource( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( session->region == NULL ) + { + session->setError( FML_ERR_INVALID_REGION, "FieldML session has no region" ); + return FML_INVALID_HANDLE; + } + + DataSource *source = objectAsDataSource( session, objectHandle ); + if( source == NULL ) + { + return FML_INVALID_HANDLE; + } + + if( source->resource == NULL ) + { + return FML_ERR_MISCONFIGURED_OBJECT; + } + + return source->resource->region->getNamedObject( source->resource->name ); +} + + +char * Fieldml_GetArrayDataSourceLocation( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return NULL; + } + + ArrayDataSource *source = getArrayDataSource( session, objectHandle ); + if( source == NULL ) + { + return NULL; + } + + return cstrCopy( source->location ); +} + + +int Fieldml_CopyArrayDataSourceLocation( FmlSessionHandle handle, FmlObjectHandle objectHandle, char * buffer, int bufferLength ) +{ + return cappedCopyAndFree( Fieldml_GetArrayDataSourceLocation( handle, objectHandle ), buffer, bufferLength ); +} + + +int Fieldml_GetArrayDataSourceRank( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return -1; + } + + FieldmlObject *object = getObject( session, objectHandle ); + if( object == NULL ) + { + return -1; + } + if( object->objectType != FHT_DATA_SOURCE ) + { + session->setError( FML_ERR_INVALID_OBJECT, "Cannot get array data source rank. Must be a data source." ); + return -1; + } + + DataSource *source = (DataSource*)object; + if( source->sourceType == FML_DATA_SOURCE_ARRAY ) + { + ArrayDataSource *arraySource = (ArrayDataSource*)source; + return arraySource->rank; + } + + session->setError( FML_ERR_INVALID_OBJECT, "Cannot get array data source rank. Must be an array data source." ); + return -1; +} + + +FmlErrorNumber Fieldml_GetArrayDataSourceSizes( FmlSessionHandle handle, FmlObjectHandle objectHandle, int *sizes ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return session->getLastError(); + } + + ArrayDataSource *source = getArrayDataSource( session, objectHandle ); + if( source == NULL ) + { + return session->getLastError(); + } + + for( int i = 0; i < source->rank; i++ ) + { + sizes[i] = source->sizes[i]; + } + + return FML_ERR_NO_ERROR; +} + + +FmlErrorNumber Fieldml_SetArrayDataSourceSizes( FmlSessionHandle handle, FmlObjectHandle objectHandle, int *sizes ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return session->getLastError(); + } + + ArrayDataSource *source = getArrayDataSource( session, objectHandle ); + if( source == NULL ) + { + return session->getLastError(); + } + + for( int i = 0; i < source->rank; i++ ) + { + if( sizes[i] < 0 ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, objectHandle, "Cannot set array data sizes. Invalid size." ); + } + } + + source->sizes.clear(); + for( int i = 0; i < source->rank; i++ ) + { + source->sizes.push_back( sizes[i] ); + } + + return FML_ERR_NO_ERROR; +} + + +FmlErrorNumber Fieldml_GetArrayDataSourceRawSizes( FmlSessionHandle handle, FmlObjectHandle objectHandle, int *sizes ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return session->getLastError(); + } + + ArrayDataSource *source = getArrayDataSource( session, objectHandle ); + if( source == NULL ) + { + return session->getLastError(); + } + + for( int i = 0; i < source->rank; i++ ) + { + sizes[i] = source->rawSizes[i]; + } + + return FML_ERR_NO_ERROR; +} + + +FmlErrorNumber Fieldml_SetArrayDataSourceRawSizes( FmlSessionHandle handle, FmlObjectHandle objectHandle, int *sizes ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return session->getLastError(); + } + + ArrayDataSource *source = getArrayDataSource( session, objectHandle ); + if( source == NULL ) + { + return session->getLastError(); + } + + for( int i = 0; i < source->rank; i++ ) + { + if( sizes[i] <= 0 ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, "Cannot set array data raw size. Invalid size." ); + } + } + + source->rawSizes.clear(); + for( int i = 0; i < source->rank; i++ ) + { + source->rawSizes.push_back( sizes[i] ); + } + + return FML_ERR_NO_ERROR; +} + + +FmlErrorNumber Fieldml_GetArrayDataSourceOffsets( FmlSessionHandle handle, FmlObjectHandle objectHandle, int *offsets ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return session->getLastError(); + } + + ArrayDataSource *source = getArrayDataSource( session, objectHandle ); + if( source == NULL ) + { + return session->getLastError(); + } + + for( int i = 0; i < source->rank; i++ ) + { + offsets[i] = source->offsets[i]; + } + + return FML_ERR_NO_ERROR; +} + + +FmlErrorNumber Fieldml_SetArrayDataSourceOffsets( FmlSessionHandle handle, FmlObjectHandle objectHandle, int *offsets ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return session->getLastError(); + } + + ArrayDataSource *source = getArrayDataSource( session, objectHandle ); + if( source == NULL ) + { + return session->getLastError(); + } + + for( int i = 0; i < source->rank; i++ ) + { + if( offsets[i] < 0 ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_3, "Cannot set array data offset. Invalid offset." ); + } + } + + source->offsets.clear(); + for( int i = 0; i < source->rank; i++ ) + { + source->offsets.push_back( offsets[i] ); + } + + return FML_ERR_NO_ERROR; +} + + +FmlObjectHandle Fieldml_CreateArrayDataSource( FmlSessionHandle handle, const char * name, FmlObjectHandle resourceHandle, const char * location, int rank ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_ERR_UNKNOWN_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create array data source. Invalid name." ); + return FML_INVALID_HANDLE; + } + if( location == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_4, "Cannot create array data source. Invalid location." ); + return FML_INVALID_HANDLE; + } + + if( !checkLocal( session, resourceHandle ) ) + { + return session->getLastError(); + } + + if( rank <= 0 ) + { + return session->setError( FML_ERR_INVALID_PARAMETER_5, "Cannot create array data source. Invalid rank." ); + } + + FieldmlObject *object = getObject( session, resourceHandle ); + if( object == NULL ) + { + return session->getLastError(); + } + if( object->objectType != FHT_DATA_RESOURCE ) + { + return session->setError( FML_ERR_INVALID_OBJECT, resourceHandle, "Cannot create array data source. Must be a data resource." ); + } + + DataResource *dataResource = getDataResource( session, resourceHandle ); + + ArrayDataSource *source = new ArrayDataSource( name, session->region, dataResource, location, rank ); + + session->setError( FML_ERR_NO_ERROR, "" ); + FmlObjectHandle sourceHandle = addObject( session, source ); + + dataResource->dataSources.push_back( sourceHandle ); + + return sourceHandle; +} + + +int Fieldml_CreateConstantEvaluator( FmlSessionHandle handle, const char * name, const char * literal, FmlObjectHandle valueType ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return FML_INVALID_HANDLE; + } + if( name == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_2, "Cannot create constant evaluator. Invalid name." ); + return FML_INVALID_HANDLE; + } + if( literal == NULL ) + { + session->setError( FML_ERR_INVALID_PARAMETER_3, "Cannot create constant evaluator. Invalid value." ); + return FML_INVALID_HANDLE; + } + + if( !checkLocal( session, valueType ) ) + { + return session->getLastError(); + } + + if( !checkIsValueType( session, valueType, true, true, false, true ) ) + { + session->setError( FML_ERR_INVALID_PARAMETER_4, valueType, "Cannot create constant evaluator. Invalid type." ); + return FML_INVALID_HANDLE; + } + + ConstantEvaluator *evaluator = new ConstantEvaluator( name, session->region, literal, valueType ); + + session->setError( FML_ERR_NO_ERROR, "" ); + return addObject( session, evaluator ); +} + + +char * Fieldml_GetConstantEvaluatorValueString( FmlSessionHandle handle, FmlObjectHandle objectHandle ) +{ + FieldmlSession *session = FieldmlSession::handleToSession( handle ); + ERROR_AUTOSTACK( session ); + + if( session == NULL ) + { + return NULL; + } + + ConstantEvaluator *evaluator = ConstantEvaluator::checkedCast( session, objectHandle ); + if( evaluator != NULL ) + { + return cstrCopy( evaluator->valueString ); + } + + session->setError( FML_ERR_INVALID_OBJECT, objectHandle, "Cannot get constant evaluator value. Invalid object." ); + return NULL; +} + + +int Fieldml_CopyConstantEvaluatorValueString( FmlSessionHandle handle, FmlObjectHandle objectHandle, char * buffer, int bufferLength ) +{ + return cappedCopyAndFree( Fieldml_GetConstantEvaluatorValueString( handle, objectHandle ), buffer, bufferLength ); +} diff --git a/core/src/fieldml_api.h b/core/src/fieldml_api.h index 8eb3618..40f603d 100644 --- a/core/src/fieldml_api.h +++ b/core/src/fieldml_api.h @@ -469,6 +469,12 @@ FmlObjectHandle Fieldml_GetObjectByName( FmlSessionHandle handle, const char * n */ FmlObjectHandle Fieldml_GetObjectByDeclaredName( FmlSessionHandle handle, const char * name ); +/** + * \return A handle to the object with the given declared name which resides in the + * import with the given href. + */ +FmlObjectHandle Fieldml_GetObjectByDeclaredNameAndHref( FmlSessionHandle handle, const char* name, const char* href ); + /** * \return 1 if the given object is local, 0 if not, or -1 on error. isDeclaredOnly is true, only objects that have been declared locally will return true. * @@ -509,6 +515,12 @@ int Fieldml_CopyObjectName( FmlSessionHandle handle, FmlObjectHandle objectHandl */ char * Fieldml_GetObjectDeclaredName( FmlSessionHandle handle, FmlObjectHandle objectHandle ); +/** + * \return The given object's declared href. This is the href (URL) of the region + * in which the object was declared. + * \see Fieldml_GetObjectDeclaredName + */ +char * Fieldml_GetObjectDeclaredHref( FmlSessionHandle handle, FmlObjectHandle objectHandle ); /** * Copies the given object's declared name into the given buffer. diff --git a/core/src/fieldml_structs.cpp b/core/src/fieldml_structs.cpp index a52dfad..397a814 100644 --- a/core/src/fieldml_structs.cpp +++ b/core/src/fieldml_structs.cpp @@ -50,10 +50,11 @@ using namespace std; // //======================================================================== -FieldmlObject::FieldmlObject( const string _name, FieldmlHandleType _type, bool _isVirtual ) : - name( _name ), - objectType( _type ), - isVirtual( _isVirtual ) +FieldmlObject::FieldmlObject( const std::string _name, FieldmlRegion* _region, FieldmlHandleType _type, bool _isVirtual ) : + name( _name ), + region( _region ), + objectType( _type ), + isVirtual( _isVirtual ) { intValue = 0; } @@ -64,16 +65,17 @@ FieldmlObject::~FieldmlObject() } -ElementSequence::ElementSequence( const string _name, FmlObjectHandle _elementType ) : - FieldmlObject( _name, FHT_UNKNOWN, false ), - elementType( _elementType ) +ElementSequence::ElementSequence( const std::string _name, + FieldmlRegion* _region, FmlObjectHandle _elementType ) : + FieldmlObject( _name, _region, FHT_UNKNOWN, false ), + elementType( _elementType ) { } -EnsembleType::EnsembleType( const string _name, bool _isComponentEnsemble, bool _isVirtual ) : - FieldmlObject( _name, FHT_ENSEMBLE_TYPE, _isVirtual ), - isComponentEnsemble( _isComponentEnsemble ) +EnsembleType::EnsembleType( const std::string _name, FieldmlRegion* _region, bool _isComponentEnsemble, bool _isVirtual ) : + FieldmlObject( _name, _region, FHT_ENSEMBLE_TYPE, _isVirtual ), + isComponentEnsemble( _isComponentEnsemble ) { membersType = FML_ENSEMBLE_MEMBER_UNKNOWN; count = 0; @@ -83,21 +85,21 @@ EnsembleType::EnsembleType( const string _name, bool _isComponentEnsemble, bool } -BooleanType::BooleanType( const string _name, bool _isVirtual ) : - FieldmlObject( _name, FHT_BOOLEAN_TYPE, _isVirtual ) +BooleanType::BooleanType( const std::string _name, FieldmlRegion* _region, bool _isVirtual ) : + FieldmlObject( _name, _region, FHT_BOOLEAN_TYPE, _isVirtual ) { } -ContinuousType::ContinuousType( const string _name, bool _isVirtual ) : - FieldmlObject( _name, FHT_CONTINUOUS_TYPE, _isVirtual ) +ContinuousType::ContinuousType( const std::string _name, FieldmlRegion* _region, bool _isVirtual ) : + FieldmlObject( _name, _region, FHT_CONTINUOUS_TYPE, _isVirtual ) { componentType = FML_INVALID_HANDLE; } -MeshType::MeshType( const string _name, bool _isVirtual ) : - FieldmlObject( _name, FHT_MESH_TYPE, _isVirtual ) +MeshType::MeshType( const std::string _name, FieldmlRegion* _region, bool _isVirtual ) : + FieldmlObject( _name, _region, FHT_MESH_TYPE, _isVirtual ) { shapes = FML_INVALID_HANDLE; chartType = FML_INVALID_HANDLE; @@ -105,8 +107,9 @@ MeshType::MeshType( const string _name, bool _isVirtual ) : } -DataResource::DataResource( const string _name, FieldmlDataResourceType _resourceType, const string _format, const string _description ) : - FieldmlObject( _name, FHT_DATA_RESOURCE, false ), +DataResource::DataResource( const std::string _name, FieldmlRegion* _region, + FieldmlDataResourceType _resourceType, const string _format, const string _description ) : + FieldmlObject( _name, _region, FHT_DATA_RESOURCE, false ), resourceType( _resourceType ), format( _format ), description( _description ) @@ -455,18 +458,20 @@ DokArrayDataDescription::~DokArrayDataDescription() } -DataSource::DataSource( const std::string _name, DataResource *_resource, FieldmlDataSourceType _type ) : - FieldmlObject( _name, FHT_DATA_SOURCE, false ), - resource( _resource ), - sourceType( _type ) +DataSource::DataSource( const std::string _name, FieldmlRegion* _region, + DataResource *_resource, FieldmlDataSourceType _type ) : + FieldmlObject( _name, _region, FHT_DATA_SOURCE, false ), + resource( _resource ), + sourceType( _type ) { } -ArrayDataSource:: ArrayDataSource( const string _name, DataResource *_resource, const string _location, int _rank ) : - DataSource( _name, _resource, FML_DATA_SOURCE_ARRAY ), - rank( _rank ), - location( _location ) +ArrayDataSource:: ArrayDataSource( const string _name, FieldmlRegion* _region, + DataResource *_resource, const string _location, int _rank ) : + DataSource( _name, _region, _resource, FML_DATA_SOURCE_ARRAY ), + rank( _rank ), + location( _location ) { rawSizes.assign( rank, 0 ); sizes.assign( rank, 0 ); diff --git a/core/src/fieldml_structs.h b/core/src/fieldml_structs.h index a9175b2..37db1b4 100644 --- a/core/src/fieldml_structs.h +++ b/core/src/fieldml_structs.h @@ -50,18 +50,21 @@ #include "SimpleMap.h" #include "SimpleBitset.h" +class FieldmlRegion; + class FieldmlObject { public: const FieldmlHandleType objectType; const std::string name; + FieldmlRegion* region; //Virtual objects are either imports, or objects which are strict sub-objects (e.g. component ensembles, mesh element/chart arguments)/ const bool isVirtual; int intValue; - FieldmlObject( const std::string _name, FieldmlHandleType _type, bool _isVirtual ); + FieldmlObject( const std::string _name, FieldmlRegion* _region, FieldmlHandleType _type, bool _isVirtual ); virtual ~FieldmlObject(); }; @@ -85,7 +88,7 @@ class EnsembleType : FmlObjectHandle dataSource; - EnsembleType( const std::string _name, bool _isComponentEnsemble, bool _isVirtual ); + EnsembleType( const std::string _name, FieldmlRegion* _region, bool _isComponentEnsemble, bool _isVirtual ); }; @@ -97,7 +100,7 @@ class ElementSequence : SimpleBitset members; - ElementSequence( const std::string _name, FmlObjectHandle _componentType ); + ElementSequence( const std::string _name, FieldmlRegion* _region, FmlObjectHandle _componentType ); }; @@ -105,7 +108,7 @@ class BooleanType : public FieldmlObject { public: - BooleanType( const std::string _name, bool _isVirtual ); + BooleanType( const std::string _name, FieldmlRegion* _region, bool _isVirtual ); }; @@ -115,7 +118,7 @@ class ContinuousType : public: FmlObjectHandle componentType; - ContinuousType( const std::string _name, bool _isVirtual ); + ContinuousType( const std::string _name, FieldmlRegion* _region, bool _isVirtual ); }; @@ -127,7 +130,7 @@ class MeshType : FmlObjectHandle elementsType; FmlObjectHandle shapes; - MeshType( const std::string _name, bool _isVirtual ); + MeshType( const std::string _name, FieldmlRegion* _region, bool _isVirtual ); }; @@ -145,7 +148,7 @@ class DataResource : std::vector dataSources; - DataResource( const std::string _name, FieldmlDataResourceType _type, const std::string _format, const std::string _description ); + DataResource( const std::string _name, FieldmlRegion* _region, FieldmlDataResourceType _type, const std::string _format, const std::string _description ); virtual ~DataResource(); }; @@ -155,7 +158,7 @@ class DataSource : public FieldmlObject { protected: - DataSource( const std::string _name, DataResource *_resource, FieldmlDataSourceType _type ); + DataSource( const std::string _name, FieldmlRegion* _region, DataResource *_resource, FieldmlDataSourceType _type ); public: const FieldmlDataSourceType sourceType; @@ -184,7 +187,7 @@ class ArrayDataSource : //NOTE: Optional for formats that internally specify sizes. std::vector rawSizes; - ArrayDataSource( const std::string _name, DataResource *_resource, const std::string _location, int _rank ); + ArrayDataSource( const std::string _name, FieldmlRegion* _region, DataResource *_resource, const std::string _location, int _rank ); virtual ~ArrayDataSource(); }; diff --git a/io/src/FieldmlIoApi.cpp b/io/src/FieldmlIoApi.cpp index cc42d5a..bf5e01b 100644 --- a/io/src/FieldmlIoApi.cpp +++ b/io/src/FieldmlIoApi.cpp @@ -75,12 +75,6 @@ FmlIoErrorNumber FieldmlIo_GetLastError() FmlReaderHandle Fieldml_OpenReader( FmlSessionHandle handle, FmlObjectHandle objectHandle ) { - if( Fieldml_IsObjectLocal( handle, objectHandle, 0 ) != 1 ) - { - FieldmlIoSession::getSession().setError( FML_IOERR_NONLOCAL_OBJECT ); - return FML_INVALID_HANDLE; - } - ArrayDataReader *reader = NULL; if( Fieldml_GetDataSourceType( handle, objectHandle ) == FML_DATA_SOURCE_ARRAY ) { diff --git a/jni/fieldml_api.i b/jni/fieldml_api.i index 5606fc2..0ccaa5e 100644 --- a/jni/fieldml_api.i +++ b/jni/fieldml_api.i @@ -81,7 +81,7 @@ %pragma(java) jniclasscode=%{ static { - System.loadLibrary("fieldml_jni_0.4"); + System.loadLibrary("fieldml_jni_0.5"); } %} diff --git a/jni/fieldml_io.i b/jni/fieldml_io.i index ecb5fe7..1a28e9a 100644 --- a/jni/fieldml_io.i +++ b/jni/fieldml_io.i @@ -81,7 +81,7 @@ %pragma(java) jniclasscode=%{ static { - System.loadLibrary("fieldml_io_jni_0.4"); + System.loadLibrary("fieldml_io_jni_0.5"); } %}