00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00071 #ifndef __PLUGFUNCTION_HPP__
00072 #define __PLUGFUNCTION_HPP__
00073
00074 #include <string>
00075 #include <boost/filesystem/path.hpp>
00076 #include <glibmm/threadpool.h>
00077
00078 #include <openfluid/dllexport.hpp>
00079 #include <openfluid/base/FuncSignature.hpp>
00080 #include <openfluid/base/StdoutFileOStream.hpp>
00081 #include <openfluid/base/ExecMsgs.hpp>
00082 #include <openfluid/base/EnvProperties.hpp>
00083 #include <openfluid/base/SimStatus.hpp>
00084 #include <openfluid/core/TypeDefs.hpp>
00085 #include <openfluid/base/LoopMacros.hpp>
00086 #include <openfluid/core/DateTime.hpp>
00087 #include <openfluid/core/Unit.hpp>
00088 #include <openfluid/core/CoreRepository.hpp>
00089 #include <openfluid/core/Event.hpp>
00090 #include <openfluid/core/EventsColl.hpp>
00091
00092
00093
00094
00095
00099 #define PLUGFUNCTION_PROC_NAME "GetPlugFunction"
00100
00104 #define PLUGSIGNATURE_PROC_NAME "GetPlugSignature"
00105
00109 #define PLUGSDKVERSION_PROC_NAME "GetPlugSDKVersion"
00110
00111
00112
00116 #define DECLARE_PLUGIN_HOOKS \
00117 extern "C" \
00118 { \
00119 DLLEXPORT std::string GetPlugSDKVersion(); \
00120 DLLEXPORT openfluid::base::PluggableFunction* GetPlugFunction(); \
00121 DLLEXPORT openfluid::base::FunctionSignature* GetPlugSignature(); \
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00135 #define DEFINE_FUNCTION_HOOK(pluginclassname) \
00136 std::string GetPlugSDKVersion() \
00137 { \
00138 return std::string(openfluid::config::FULL_VERSION); \
00139 } \
00140 \
00141 openfluid::base::PluggableFunction* GetPlugFunction() \
00142 { \
00143 return new pluginclassname(); \
00144 }
00145
00146
00147
00148
00149
00150
00151
00152 namespace openfluid { namespace base {
00153
00154
00155
00165 class DLLEXPORT PluggableFunction
00166 {
00167
00168 private:
00169
00173 openfluid::core::CoreRepository* mp_InternalCoreData;
00174
00175
00179 openfluid::base::ExecutionMessages* mp_ExecMsgs;
00180
00181
00185 const openfluid::base::EnvironmentProperties* mp_FunctionEnv;
00186
00187
00191 openfluid::core::FuncParamsMap_t m_ParamsMap;
00192
00196 openfluid::base::FuncID_t m_FunctionID;
00197
00198 unsigned int m_MaxThreads;
00199
00200 bool m_Initialized;
00201
00202 static bool IsUnitIDInPtrList(const openfluid::core::UnitsPtrList_t* UnitsList,
00203 const openfluid::core::UnitID_t& ID);
00204
00205 static std::string generateDotEdge(std::string SrcClass, std::string SrcID,
00206 std::string DestClass, std::string DestID,
00207 std::string Options);
00208
00209
00210 protected:
00211
00212
00216 openfluid::core::CoreRepository* mp_CoreData;
00217
00225 void OPENFLUID_AppendVariable(openfluid::core::Unit *UnitPtr,
00226 const openfluid::core::VariableName_t VarName,
00227 const openfluid::core::Value& Val);
00228
00235 void OPENFLUID_AppendVariable(openfluid::core::Unit& aUnit,
00236 const openfluid::core::VariableName_t VarName,
00237 const openfluid::core::Value& Val);
00238
00245 void OPENFLUID_AppendVariable(openfluid::core::Unit *UnitPtr,
00246 const openfluid::core::VariableName_t VarName,
00247 const double Val);
00248
00255 void OPENFLUID_AppendVariable(openfluid::core::Unit *UnitPtr,
00256 const openfluid::core::VariableName_t VarName,
00257 const long Val);
00258
00265 void OPENFLUID_AppendVariable(openfluid::core::Unit *UnitPtr,
00266 const openfluid::core::VariableName_t VarName,
00267 const bool Val);
00268
00275 void OPENFLUID_AppendVariable(openfluid::core::Unit *UnitPtr,
00276 const openfluid::core::VariableName_t VarName,
00277 const std::string& Val);
00278
00279
00287 void OPENFLUID_SetVariable(openfluid::core::Unit *UnitPtr,
00288 const openfluid::core::VariableName_t VarName,
00289 const openfluid::core::TimeStep_t Step,
00290 const openfluid::core::Value& Val);
00291
00299 void OPENFLUID_SetVariable(openfluid::core::Unit *UnitPtr,
00300 const openfluid::core::VariableName_t VarName,
00301 const openfluid::core::TimeStep_t Step,
00302 const double Val);
00303
00311 void OPENFLUID_SetVariable(openfluid::core::Unit *UnitPtr,
00312 const openfluid::core::VariableName_t VarName,
00313 const openfluid::core::TimeStep_t Step,
00314 const long Val);
00315
00323 void OPENFLUID_SetVariable(openfluid::core::Unit *UnitPtr,
00324 const openfluid::core::VariableName_t VarName,
00325 const openfluid::core::TimeStep_t Step,
00326 const bool Val);
00327
00335 void OPENFLUID_SetVariable(openfluid::core::Unit *UnitPtr,
00336 const openfluid::core::VariableName_t VarName,
00337 const openfluid::core::TimeStep_t Step,
00338 const std::string Val);
00339
00340
00349 void OPENFLUID_GetVariable(const openfluid::core::Unit* UnitPtr,
00350 const openfluid::core::VariableName_t VarName,
00351 const openfluid::core::TimeStep_t Step,
00352 openfluid::core::Value* Val) const;
00353
00361 void OPENFLUID_GetVariable(const openfluid::core::Unit* UnitPtr,
00362 const openfluid::core::VariableName_t VarName,
00363 const openfluid::core::TimeStep_t Step,
00364 openfluid::core::Value& Val) const;
00365
00374 void OPENFLUID_GetVariable(const openfluid::core::Unit* UnitPtr,
00375 const openfluid::core::VariableName_t VarName,
00376 const openfluid::core::TimeStep_t Step,
00377 double* Val) const;
00378
00386 void OPENFLUID_GetVariable(const openfluid::core::Unit* UnitPtr,
00387 const openfluid::core::VariableName_t VarName,
00388 const openfluid::core::TimeStep_t Step,
00389 double& Val) const;
00398 void OPENFLUID_GetVariable(const openfluid::core::Unit* UnitPtr,
00399 const openfluid::core::VariableName_t VarName,
00400 const openfluid::core::TimeStep_t Step,
00401 long* Val) const;
00402
00410 void OPENFLUID_GetVariable(const openfluid::core::Unit* UnitPtr,
00411 const openfluid::core::VariableName_t VarName,
00412 const openfluid::core::TimeStep_t Step,
00413 long& Val) const;
00414
00423 void OPENFLUID_GetVariable(const openfluid::core::Unit* UnitPtr,
00424 const openfluid::core::VariableName_t VarName,
00425 const openfluid::core::TimeStep_t Step,
00426 bool* Val) const;
00427
00435 void OPENFLUID_GetVariable(const openfluid::core::Unit* UnitPtr,
00436 const openfluid::core::VariableName_t VarName,
00437 const openfluid::core::TimeStep_t Step,
00438 bool& Val) const;
00439
00440
00449 void OPENFLUID_GetVariable(const openfluid::core::Unit* UnitPtr,
00450 const openfluid::core::VariableName_t VarName,
00451 const openfluid::core::TimeStep_t Step,
00452 std::string* Val) const;
00453
00461 void OPENFLUID_GetVariable(const openfluid::core::Unit* UnitPtr,
00462 const openfluid::core::VariableName_t VarName,
00463 const openfluid::core::TimeStep_t Step,
00464 std::string& Val) const;
00465
00471 bool OPENFLUID_IsVariableExist(const openfluid::core::Unit *UnitPtr,
00472 const openfluid::core::VariableName_t VarName) const;
00473
00480 bool OPENFLUID_IsVariableExist(const openfluid::core::Unit *UnitPtr,
00481 const openfluid::core::VariableName_t VarName,
00482 const openfluid::core::TimeStep_t Step) const;
00483
00492 bool OPENFLUID_IsVariableExist(const openfluid::core::Unit *UnitPtr,
00493 const openfluid::core::VariableName_t VarName,
00494 const openfluid::core::TimeStep_t Step,
00495 const openfluid::core::Value::Type ValueType) const;
00496
00504 bool OPENFLUID_IsTypedVariableExist(const openfluid::core::Unit *UnitPtr,
00505 const openfluid::core::VariableName_t VarName,
00506 const openfluid::core::Value::Type VarType) const;
00507
00516 bool OPENFLUID_IsTypedVariableExist(const openfluid::core::Unit *UnitPtr,
00517 const openfluid::core::VariableName_t VarName,
00518 const openfluid::core::TimeStep_t Step,
00519 const openfluid::core::Value::Type VarType) const;
00520
00521
00528 void OPENFLUID_SetInputData(openfluid::core::Unit *UnitPtr,
00529 const openfluid::core::InputDataName_t& InputName,
00530 const openfluid::core::Value& Val);
00531
00538 void OPENFLUID_SetInputData(openfluid::core::Unit *UnitPtr,
00539 const openfluid::core::InputDataName_t& InputName,
00540 const double& Val);
00541
00548 void OPENFLUID_SetInputData(openfluid::core::Unit *UnitPtr,
00549 const openfluid::core::InputDataName_t& InputName,
00550 const long& Val);
00551
00558 void OPENFLUID_SetInputData(openfluid::core::Unit *UnitPtr,
00559 const openfluid::core::InputDataName_t& InputName,
00560 const std::string& Val);
00561
00562
00569 void OPENFLUID_GetInputData(const openfluid::core::Unit *UnitPtr,
00570 const openfluid::core::InputDataName_t InputName,
00571 openfluid::core::StringValue& Val) const;
00572
00580 void OPENFLUID_GetInputData(const openfluid::core::Unit *UnitPtr,
00581 const openfluid::core::InputDataName_t InputName,
00582 openfluid::core::DoubleValue* Val) const;
00583
00590 void OPENFLUID_GetInputData(const openfluid::core::Unit *UnitPtr,
00591 const openfluid::core::InputDataName_t InputName,
00592 openfluid::core::DoubleValue& Val) const;
00593
00601 void OPENFLUID_GetInputData(const openfluid::core::Unit *UnitPtr,
00602 const openfluid::core::InputDataName_t InputName,
00603 openfluid::core::VectorValue* Val) const;
00604
00611 void OPENFLUID_GetInputData(const openfluid::core::Unit *UnitPtr,
00612 const openfluid::core::InputDataName_t InputName,
00613 openfluid::core::VectorValue& Val) const;
00614
00621 void OPENFLUID_GetInputData(const openfluid::core::Unit *UnitPtr,
00622 const openfluid::core::InputDataName_t InputName,
00623 openfluid::core::MatrixValue& Val) const;
00624
00632 void OPENFLUID_GetInputData(const openfluid::core::Unit *UnitPtr,
00633 const openfluid::core::InputDataName_t InputName,
00634 double *Val) const;
00635
00642 void OPENFLUID_GetInputData(const openfluid::core::Unit *UnitPtr,
00643 const openfluid::core::InputDataName_t InputName,
00644 double& Val) const;
00645
00653 void OPENFLUID_GetInputData(const openfluid::core::Unit *UnitPtr,
00654 const openfluid::core::InputDataName_t InputName,
00655 long *Val) const;
00656
00663 void OPENFLUID_GetInputData(const openfluid::core::Unit *UnitPtr,
00664 const openfluid::core::InputDataName_t InputName,
00665 long& Val) const;
00666
00674 void OPENFLUID_GetInputData(const openfluid::core::Unit *UnitPtr,
00675 const openfluid::core::InputDataName_t InputName,
00676 std::string *Val) const;
00677
00684 void OPENFLUID_GetInputData(const openfluid::core::Unit *UnitPtr,
00685 const openfluid::core::InputDataName_t InputName,
00686 std::string& Val) const;
00687
00693 bool OPENFLUID_IsInputDataExist(const openfluid::core::Unit *UnitPtr,
00694 const openfluid::core::InputDataName_t InputName) const;
00695
00696
00703 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00704 const openfluid::core::FuncParamKey_t ParamName,
00705 openfluid::core::StringValue& Val) const;
00706
00713 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00714 const openfluid::core::FuncParamKey_t ParamName,
00715 openfluid::core::DoubleValue& Val) const;
00716
00723 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00724 const openfluid::core::FuncParamKey_t ParamName,
00725 openfluid::core::VectorValue& Val) const;
00726
00733 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00734 const openfluid::core::FuncParamKey_t ParamName,
00735 openfluid::core::MatrixValue& Val) const;
00736
00744 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00745 const openfluid::core::FuncParamKey_t ParamName,
00746 double *Val) const;
00747
00754 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00755 const openfluid::core::FuncParamKey_t ParamName,
00756 double& Val) const;
00757
00765 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00766 const openfluid::core::FuncParamKey_t ParamName,
00767 long *Val) const;
00768
00775 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00776 const openfluid::core::FuncParamKey_t ParamName,
00777 long& Val) const;
00778
00786 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00787 const openfluid::core::FuncParamKey_t ParamName,
00788 float *Val) const;
00789
00796 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00797 const openfluid::core::FuncParamKey_t ParamName,
00798 float& Val) const;
00799
00807 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00808 const openfluid::core::FuncParamKey_t ParamName,
00809 int *Val) const;
00810
00817 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00818 const openfluid::core::FuncParamKey_t ParamName,
00819 int& Val) const;
00820
00828 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00829 const openfluid::core::FuncParamKey_t ParamName,
00830 std::string *Val) const;
00831
00838 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00839 const openfluid::core::FuncParamKey_t ParamName,
00840 std::string& Val) const;
00841
00849 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00850 const openfluid::core::FuncParamKey_t ParamName,
00851 std::vector<std::string> *Vals) const;
00852
00859 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00860 const openfluid::core::FuncParamKey_t ParamName,
00861 std::vector<std::string>& Vals) const;
00862
00870 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00871 const openfluid::core::FuncParamKey_t ParamName,
00872 std::vector<double> *Vals) const;
00873
00880 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00881 const openfluid::core::FuncParamKey_t ParamName,
00882 std::vector<double>& Vals) const;
00883
00891 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00892 const openfluid::core::FuncParamKey_t ParamName,
00893 std::vector<long> *Vals) const;
00894
00901 bool OPENFLUID_GetFunctionParameter(const openfluid::core::FuncParamsMap_t Params,
00902 const openfluid::core::FuncParamKey_t ParamName,
00903 std::vector<long>& Vals) const;
00904
00905
00911 void OPENFLUID_AppendEvent(openfluid::core::Unit *UnitPtr,
00912 openfluid::core::Event& Ev);
00913
00914
00923 void OPENFLUID_GetEvents(const openfluid::core::Unit *UnitPtr,
00924 const openfluid::core::DateTime BeginDate,
00925 const openfluid::core::DateTime EndDate,
00926 openfluid::core::EventsCollection* Events) const;
00927
00935 void OPENFLUID_GetEvents(const openfluid::core::Unit *UnitPtr,
00936 const openfluid::core::DateTime BeginDate,
00937 const openfluid::core::DateTime EndDate,
00938 openfluid::core::EventsCollection& Events) const;
00939
00944 bool OPENFLUID_IsUnitClassExist(openfluid::core::UnitClass_t ClassName);
00945
00946
00952 bool OPENFLUID_IsUnitExist(openfluid::core::UnitClass_t ClassName,
00953 openfluid::core::UnitID_t ID);
00954
00959 void OPENFLUID_GetUnitsCount(unsigned int& UnitsCount);
00960
00967 bool OPENFLUID_GetUnitsCount(const openfluid::core::UnitClass_t ClassName,
00968 unsigned int& UnitsCount);
00969
00970
00978 bool OPENFLUID_GetUnit(const openfluid::core::UnitClass_t& ClassName,
00979 const openfluid::core::UnitID_t& ID,
00980 openfluid::core::Unit* aUnit);
00981
00982 openfluid::core::Unit* OPENFLUID_GetUnit(const openfluid::core::UnitClass_t& ClassName,
00983 const openfluid::core::UnitID_t& ID);
00984
00991 void OPENFLUID_AddUnit(openfluid::core::UnitClass_t ClassName,
00992 openfluid::core::UnitID_t ID,
00993 openfluid::core::PcsOrd_t PcsOrder);
00994
01001 void OPENFLUID_DeleteUnit(openfluid::core::UnitClass_t ClassName,
01002 openfluid::core::UnitID_t ID);
01003
01004
01013 bool OPENFLUID_AddFromToConnection(openfluid::core::UnitClass_t ClassNameFrom,
01014 openfluid::core::UnitID_t IDFrom,
01015 openfluid::core::UnitClass_t ClassNameTo,
01016 openfluid::core::UnitID_t IDTo);
01017
01024 bool OPENFLUID_AddFromToConnection(openfluid::core::Unit* FromUnit,
01025 openfluid::core::Unit* ToUnit);
01026
01035 bool OPENFLUID_RemoveFromToConnection(openfluid::core::UnitClass_t ClassNameFrom,
01036 openfluid::core::UnitID_t IDFrom,
01037 openfluid::core::UnitClass_t ClassNameTo,
01038 openfluid::core::UnitID_t IDTo);
01039
01046 bool OPENFLUID_RemoveFromToConnection(openfluid::core::Unit* FromUnit,
01047 openfluid::core::Unit* ToUnit);
01048
01049
01058 bool OPENFLUID_AddChildParentConnection(openfluid::core::UnitClass_t ClassNameChild,
01059 openfluid::core::UnitID_t IDChild,
01060 openfluid::core::UnitClass_t ClassNameParent,
01061 openfluid::core::UnitID_t IDParent);
01062
01069 bool OPENFLUID_AddChildParentConnection(openfluid::core::Unit* ChildUnit,
01070 openfluid::core::Unit* ParentUnit);
01071
01072
01081 bool OPENFLUID_RemoveChildParentConnection(openfluid::core::UnitClass_t ClassNameChild,
01082 openfluid::core::UnitID_t IDChild,
01083 openfluid::core::UnitClass_t ClassNameParent,
01084 openfluid::core::UnitID_t IDParent);
01085
01092 bool OPENFLUID_RemoveChildParentConnection(openfluid::core::Unit* ChildUnit,
01093 openfluid::core::Unit* ParentUnit);
01094
01102 bool OPENFLUID_IsUnitConnectedTo(openfluid::core::Unit* aUnit,
01103 const openfluid::core::UnitClass_t& ClassNameTo,
01104 const openfluid::core::UnitID_t& IDTo);
01105
01106
01114 bool OPENFLUID_IsUnitConnectedFrom(openfluid::core::Unit* aUnit,
01115 const openfluid::core::UnitClass_t& ClassNameFrom,
01116 const openfluid::core::UnitID_t& IDFrom);
01117
01118
01126 bool OPENFLUID_IsUnitChildOf(openfluid::core::Unit* aUnit,
01127 const openfluid::core::UnitClass_t& ClassNameParent,
01128 const openfluid::core::UnitID_t& IDParent);
01129
01130
01138 bool OPENFLUID_IsUnitParentOf(openfluid::core::Unit* aUnit,
01139 const openfluid::core::UnitClass_t& ClassNameChild,
01140 const openfluid::core::UnitID_t& IDChild);
01141
01142
01149 void OPENFLUID_BuildUnitsMatrix(const openfluid::core::UnitClass_t& UnitsClass,
01150 const unsigned int& ColsNbr,
01151 const unsigned int& RowsNbr);
01152
01153
01159 void OPENFLUID_ExportUnitsGraphAsDotFile(const std::string& Filename);
01160
01167 void OPENFLUID_RaiseWarning(std::string Sender, openfluid::core::TimeStep_t TimeStep, std::string Msg);
01168
01174 void OPENFLUID_RaiseWarning(std::string Sender, std::string Msg);
01175
01183 void OPENFLUID_RaiseWarning(std::string Sender, std::string Source, openfluid::core::TimeStep_t TimeStep, std::string Msg);
01184
01191 void OPENFLUID_RaiseWarning(std::string Sender, std::string Source, std::string Msg);
01192
01193
01200 void OPENFLUID_RaiseError(std::string Sender, openfluid::core::TimeStep_t TimeStep, std::string Msg);
01201
01207 void OPENFLUID_RaiseError(std::string Sender, std::string Msg);
01208
01216 void OPENFLUID_RaiseError(std::string Sender, std::string Source, openfluid::core::TimeStep_t TimeStep, std::string Msg);
01217
01224 void OPENFLUID_RaiseError(std::string Sender, std::string Source, std::string Msg);
01225
01226
01232 bool OPENFLUID_GetRunEnvironment(std::string Key, std::string *Val);
01233
01239 bool OPENFLUID_GetRunEnvironment(std::string Key, bool *Val);
01240
01245 inline unsigned int OPENFLUID_GetFunctionMaxThreads() const { return m_MaxThreads; };
01246
01251 void OPENFLUID_SetFunctionMaxThreads(const unsigned int& MaxNumThreads);
01252
01253
01254 StdoutAndFileOutputStream OPENFLUID_Logger;
01255
01256
01257 public:
01261 PluggableFunction();
01262
01266 virtual ~PluggableFunction();
01267
01271 void initializeFunction(openfluid::core::CoreRepository* CoreData,
01272 openfluid::base::ExecutionMessages* ExecMsgs,
01273 openfluid::base::EnvironmentProperties* FuncEnv,
01274 const unsigned int& MaxThreads,
01275 const openfluid::base::FuncID_t& FuncID);
01276
01280 void finalizeFunction();
01281
01282
01283
01287 virtual bool initParams(openfluid::core::FuncParamsMap_t Params)=0;
01288
01292 virtual bool prepareData()=0;
01293
01297 virtual bool checkConsistency()=0;
01298
01302 virtual bool initializeRun(const SimulationInfo* SimInfo)=0;
01303
01307 virtual bool runStep(const SimulationStatus* SimStatus)=0;
01308
01312 virtual bool finalizeRun(const SimulationInfo* SimInfo)=0;
01313
01314 };
01315
01316
01317 typedef PluggableFunction* (*GetPluggableFunctionProc)();
01318
01319 typedef FunctionSignature* (*GetSignatureProc)();
01320
01321 typedef std::string (*GetSDKVersionProc)();
01322
01323
01324
01325 } }
01326
01327
01328
01329 #endif
01330