<?xml version="1.0" encoding="UTF-8"?>

<!--================================================================-->
<!-- Copyright 2003 P&P Software GmbH             -->
<!--================================================================-->

<!--===================================================================
Generator meta-component for a parameter database class for the OBS 
Framework. The parameter database is implemented as a subclass of
class ParameterDatabase. This class defines the operations to access
the parameters in the database but it neither defines the
internal structure of the database nor the level robustness checks
that are performed when an external user tries to access the parameters
in the database. This code generator can generate three types of parameter
database implementations corresponding to the following three levels of 
implementation robustness:
Level 1 = The legality of parameter access operations is verified only in
          'assert' clauses
Level 2 = The legality of parameter access operations is verified in 'assert'
          clauses and additional run-time checks are performed on
          write accesses (but none on read accesses)
Level 3 = The legality of parameter access operations is verified in 'assert'
          clauses and in additional run-time checks.
          
This XSL program generates the header file of the parameter database 
class.

This XSL program processes the XML-based application model. 
===================================================================-->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.1"
    xmlns:lxslt="http://xml.apache.org/xslt"
    xmlns:redirect="org.apache.xalan.lib.Redirect"
    extension-element-prefixes="redirect">

<xsl:strip-space elements="*"/>
<xsl:output omit-xml-declaration="yes" method="text"/>

<!--===================================================================
       Include general utility rules
===================================================================-->
 <xsl:include href="ClassNameFromPath.xsl"/>
<xsl:include href="WriteCommentBody.xsl"/>
<xsl:include href="MakeFirstLetterCap.xsl"/>
<!--===================================================================
      Top-level rule 
===================================================================-->
<xsl:template match="/ObsApplication/ParameterDatabase/IndexedDatabase">
<!--===================================================================
      Define general-purpose variables
 ===================================================================-->  
  <xsl:variable name="ClassName">
        <xsl:call-template name="ClassNameFromPath">
              <xsl:with-param name="path" select="@type"/>
        </xsl:call-template>
  </xsl:variable>
  <xsl:variable name="CodeDir" select="'../'"/>
  <xsl:variable name="Level" select="RobustnessLevel/@value"/>

  <!-- start code generation                                       -->    
  <xsl:variable name="TargetFile" select="concat('/Projects/ObsFramework/src/cpp/',@type)"/>     
            
  Generating code for class <xsl:value-of select="$ClassName"/> in files <xsl:value-of select="$TargetFile"/>.h

  <!-- Check whether writing to an output file is possible -->
  <xsl:if test="not(element-available('xsl:document'))">
        FATAL ERROR: the xsl:document element is not supported. Header files cannot be written! This element
        is normally supported only in version 1.1 of XSL.
  </xsl:if>
            
  <!-- ===================================================================================
         Create the output file  
          ===================================================================================-->
  <xsl:document href="{$TargetFile}.h" omit-xml-declaration="yes" method="text">  
//
// Copyright 2003 P&amp;P Software GmbH - All Rights Reserved
//
// <xsl:value-of select="$ClassName"/>.h
//
// This file was automatically generated by an XSL program
//

#ifndef <xsl:value-of select="$ClassName"/>H
#define <xsl:value-of select="$ClassName"/>H

#include "<xsl:value-of select="$CodeDir"/>GeneralInclude/ForwardDeclarations.h"
#include "<xsl:value-of select="$CodeDir"/>GeneralInclude/BasicTypes.h"
#include "<xsl:value-of select="$CodeDir"/>Data/ParameterDatabase.h"
#include "<xsl:value-of select="$ClassName"/>_inc.h"

/**
<xsl:call-template name="WriteCommentBody">
         <xsl:with-param name="text" select="normalize-space(Description)"/>
         <xsl:with-param name="indent" select="' '"/>
</xsl:call-template> 
 * &lt;p&gt;
 * The code for this class was automatically generated by an XSL program
 * using as input the XML-based &lt;i&gt;application model&lt;/i&gt;. 
 * This class offers a pointer-oriented and robust
 * implementation of the &lt;code&gt;ParameterDatabase&lt;/code&gt; interface.
 * The price paid for the safety offered by this implementation
 * is a certain inefficiency both in terms of memory overhead and
 * run-time when accessing a parameter.
 * &lt;p&gt;
 * An indexed database maintains internal data structures that,
 * for each parameter in the database, store the following information:&lt;ul&gt;
 * &lt;li&gt;The pointer to the operational version of the parameter&lt;/li&gt;
 * &lt;li&gt;The syntactical type of the parameter&lt;/li&gt;
 * &lt;/ul&gt;
 * These internal data structures are set up and initialized by the indexed
 * database component during its configuration procedure.
 * The parameter type information allows the component to perform run-time cheks 
 * on the access to the parameter values. Checks are performed on the 
 * legality of the parameter identifier and on the use of the 
 * correct accessor method for a parameter (e.g. the value
 * of a parameter of type float should only be accessed with method 
 * &lt;code&gt;getParameterFloat&lt;/code&gt;). 
 * &lt;p&gt;
 * The memory overhead caused by this class is minimized when the 
 * parameter identifiers begin with a zero and when there are no "gaps"
 * in the parameter identifier. 
 * &lt;p&gt;
 * The default and operational tables are &lt;i&gt;not&lt;/i&gt; defined by this class.
 * This class loads the tables using methods &lt;code&gt;setDefaultTable&lt;/code&gt;
 * and &lt;code&gt;setOperationalTable&lt;/code&gt;.
 * &lt;p&gt;
 * The configuration procedure for an instance of this class is as follows: &lt;ul&gt;
 * &lt;li&gt;Load the default table (method &lt;code&gt;setDefaultTable&lt;/code&gt;)  &lt;/li&gt;
 * &lt;li&gt;Load the operational table (method &lt;code&gt;setOperationalTable&lt;/code&gt;)  &lt;/li&gt;
 * &lt;li&gt;Reset the component instance (method &lt;code&gt;reset&lt;/code&gt;)  &lt;/li&gt;
 * &lt;/ul&gt;
 * Note that an include file (&lt;code&gt;<xsl:value-of select="$ClassName"/>_inc.h&lt;/code&gt;) 
 * is also automatically generated that defines symbolic names to access the parameters in the database. 
 * &lt;p&gt;
 * The getter and setter methods are implemented to be fast and efficient but this
 * makes them vulnerable to alignement problems on some processors. For instance,
 * the setter methods for integer-valued parameters is implemened as follows: &lt;pre&gt;
 *    void DC_BasicDatabase::setParameter(TD_DatabaseId parId, int newValue) {
 *         *( (int*)(pPar[parId]) ) = newValue;
 *    }&lt;/pre&gt;
 * On some processors, the assignment will fail if location &lt;code&gt;pPar[parId]&lt;/code&gt; does not
 * correspond to a longword (4 bytes) boundary. There is no check to ensure that this
 * is the case and it is the responsibility of the user to ensure that the database map
 * is such as to avoid this type of problems. The database map is defined in the 
 * XML document that is processed by the generator meta-component that generates the
 * database implementation. A more robust (but possibly slower) implementation
 * might use the &lt;code&gt;memcpy&lt;/code&gt; library function to transfer the values of the
 * data between the database locations and the method variables.
 * @author Automatically Generated 
 * @version 1.0
 */
class <xsl:value-of select="$ClassName"/> : public ParameterDatabase {

  private:
      char* pDefaultTable;          // array of chars
      char* pOperationalTable;      // array of chars
      bool resetWasCalled;
      TD_DatabaseId tableLength;    // table length in bytes
      char** pPar;                  // pPar[i] holds the pointer to the i-th par 
      TD_DatabaseId maxParId;        // maximum value of parameter identifier

      // parType[i] holds a code representing the type of the i-th par: 
      char* parType;                 

  public:

    /**
     * Instantiate a database component 
     * The default and operational table arrays are initialized to illegal
     * values to signify that the component is not yet configured.
     * values. The table and length and the class identifier are set.
     */
    <xsl:value-of select="$ClassName"/>();

    /**
     * Copy the default table array onto the operational table array
     * and set up the internal
     * data structures that describe the position of the parameters in the
     * database and their type. 
     * An indexed database component maintains two internal data structures
     * that describe how the database is organized: &lt;ul&gt;
     * &lt;li&gt;&lt;i&gt;The parameter pointer 
     * table &lt;code&gt;pPar&lt;/code&gt;&lt;/i&gt;: 
     * &lt;code&gt;pPar[i]&lt;/code&gt;
     * holds the pointer to the database parameter with parameter
     * identifier i. The operational version of the database is used. &lt;/li&gt;
     * &lt;li&gt;&lt;i&gt;The parameter type 
     * table &lt;code&gt;parType&lt;/code&gt;&lt;/i&gt;: 
     * &lt;code&gt;parType[i]&lt;/code&gt;
     * holds an integer that encodes the type of the database parameter with parameter
     * identifier i. &lt;/li&gt;
     * &lt;/ul&gt;
     * The initialization of these two tables is hardcoded in this method.
     * The information for generating the code comes from the XML file which 
     * describes the parameter database and which is used as input for generating
     * the code for this class.
     */
    virtual void reset();

    /**
     * Load the default table. This method assumes that the default table has
     * been defined and initialized by the caller. The method does not perform
     * any action on the table. It simply loads its address and will use it
     * for accessing the table entries.
     * &lt;p&gt;
     * This is an initialization method.
     * @param pDefTable the starting address of the default table
     */
    void setDefaultTable(char* pDefTable);

    /**
     * Load the operational table. This method assumes that the operational table has
     * been defined and initialized by the caller. The method does not perform
     * any action on the table. It simply loads its address and will use it
     * for accessing the table entries.
     * &lt;p&gt;
     * This is an initialization method.
     * @param pOperTable the starting address of the operational table
     */
    void setOperationalTable(char* pOperTable);

<xsl:call-template name="setParameterMethod">
   <xsl:with-param name="type" select="'int'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>   
<xsl:call-template name="setParameterMethod">
   <xsl:with-param name="type" select="'unsigned int'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="setParameterMethod">
   <xsl:with-param name="type" select="'short'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="setParameterMethod">
   <xsl:with-param name="type" select="'unsigned short'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="setParameterMethod">
   <xsl:with-param name="type" select="'char'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="setParameterMethod">
   <xsl:with-param name="type" select="'unsigned char'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="setParameterMethod">
   <xsl:with-param name="type" select="'bool'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="setParameterMethod">
   <xsl:with-param name="type" select="'float'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="setParameterMethod">
   <xsl:with-param name="type" select="'double'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>

<xsl:call-template name="getParameterMethod">
   <xsl:with-param name="type" select="'int'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getParameterMethod">
   <xsl:with-param name="type" select="'unsigned int'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getParameterMethod">
   <xsl:with-param name="type" select="'short'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getParameterMethod">
   <xsl:with-param name="type" select="'unsigned short'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getParameterMethod">
   <xsl:with-param name="type" select="'char'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getParameterMethod">
   <xsl:with-param name="type" select="'unsigned char'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getParameterMethod">
   <xsl:with-param name="type" select="'bool'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getParameterMethod">
   <xsl:with-param name="type" select="'float'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getParameterMethod">
   <xsl:with-param name="type" select="'double'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>

<xsl:call-template name="getPointerMethod">
   <xsl:with-param name="type" select="'int'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getPointerMethod">
   <xsl:with-param name="type" select="'unsigned int'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getPointerMethod">
   <xsl:with-param name="type" select="'short'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getPointerMethod">
   <xsl:with-param name="type" select="'unsigned short'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getPointerMethod">
   <xsl:with-param name="type" select="'char'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getPointerMethod">
   <xsl:with-param name="type" select="'unsigned char'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getPointerMethod">
   <xsl:with-param name="type" select="'bool'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getPointerMethod">
   <xsl:with-param name="type" select="'float'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>
<xsl:call-template name="getPointerMethod">
   <xsl:with-param name="type" select="'double'"/>
   <xsl:with-param name="level" select="$Level"/>
   <xsl:with-param name="className" select="$ClassName"/>
</xsl:call-template>

    /**
     * Perform a class-specific configuration check on a basic database object:
     * verify that the default and operational tables have been loaded, that
     * method &lt;code&gt;reset&lt;/code&gt; has been called, and that the table length
     * is greater than zero.
     * @see #reset
     * @return true if the database object is configured, false otherwise
     */
    virtual bool isObjectConfigured();

};

#endif  
</xsl:document>
</xsl:template>

<!--================================================================-->
<!-- Utility to write out the declaration of a parameter setter     -->
<!-- method.                                                        -->
<!-- The first template parameter is the name of the type of the    -->
<!-- database parameter. The second template parameter is the       -->
<!-- robustness level of the database.                              -->
<!--================================================================-->

<xsl:template name="setParameterMethod">
  <xsl:param name="type"/>
  <xsl:param name="level"/>
  <xsl:variable name="normalizedType">
      <xsl:call-template name="MakeFirstLetterCap">
        <xsl:with-param name="before" select="''"/>
        <xsl:with-param name="after" select="$type"/>
      </xsl:call-template>
   </xsl:variable>
    /**
     * Set the current value of a parameter interpreted as a parameter of
     * type <xsl:value-of select="$type"/>.
     * Run-time checks are performed on the legality of the parameter identifier
     * and on the correctness of the parameter type (i.e. it is verified that
     * the parameter being accessed is internally recorded as a parameter of 
     * type <xsl:value-of select="$type"/>). <xsl:text/>
   <xsl:choose>
     <xsl:when test="$level='1'">
     * Failure of the checks results in
     * the generation of an assert error. If assertions are disabled, the checks
     * are ineffective. 
     </xsl:when>
     <xsl:otherwise>
     * Failure of the checks results in
     * the generation of an assert error and in the generation of an event report
     * for an event of type EVT_ILLEGAL_DB_ACCESS. The database parameter is not
     * updated if the check fails.
     </xsl:otherwise>
   </xsl:choose> 
     <xsl:text/>* @param parId the identifier of the parameter to be set
     * @param newValue the new current value of the parameter
     */
    virtual void setParameter(TD_DatabaseId parId, <xsl:value-of select="$type"/> newValue);
</xsl:template>

<!--================================================================-->
<!-- Utility to write out the declaration of a parameter getter     -->
<!-- method.                                                        -->
<!-- The first template parameter is the name of the type of the    -->
<!-- database parameter. The second template parameter is the       -->
<!-- robustness level of the database.                              -->
<!--================================================================-->

<xsl:template name="getParameterMethod">
  <xsl:param name="type"/>
  <xsl:param name="level"/>
  <xsl:variable name="normalizedType">
      <xsl:call-template name="MakeFirstLetterCap">
        <xsl:with-param name="before" select="''"/>
        <xsl:with-param name="after" select="$type"/>
      </xsl:call-template>
   </xsl:variable>
    /**
     * Get the current value of a parameter interpreted as a parameter of
     * type <xsl:value-of select="$type"/>.
     * Run-time checks are performed on the legality of the parameter identifier
     * and on the correctness of the parameter type (i.e. it is verified that
     * the parameter being accessed is internally recorded as a parameter of 
     * type <xsl:value-of select="$type"/>). <xsl:text/>
   <xsl:choose>
     <xsl:when test="$level='3'">
     * Failure of the checks results in
     * the generation of an assert error and in the generation of an event report
     * for an event of type EVT_ILLEGAL_DB_ACCESS. The method returns a default value 
     * of zero.
     </xsl:when>
     <xsl:otherwise>
     * Failure of the checks results in
     * the generation of an assert error. If assertions are disabled, the checks
     * are ineffective. 
     </xsl:otherwise>
   </xsl:choose> 
     <xsl:text/>* @param parId the identifier of the parameter to be set
     * @return the current value of the parameter
     */
    virtual <xsl:value-of select="$type"/> getParameter<xsl:value-of 
                select="$normalizedType"/>(TD_DatabaseId parId);
</xsl:template>

<!--================================================================-->
<!-- Utility to write out the declaration of a parameter pointer    -->
<!-- getter method.                                                 -->
<!-- The first template parameter is the name of the type of the    -->
<!-- database parameter. The second template parameter is the       -->
<!-- robustness level of the database.                              -->
<!--================================================================-->

<xsl:template name="getPointerMethod">
  <xsl:param name="type"/>
  <xsl:param name="level"/>
  <xsl:variable name="normalizedType">
      <xsl:call-template name="MakeFirstLetterCap">
        <xsl:with-param name="before" select="''"/>
        <xsl:with-param name="after" select="$type"/>
      </xsl:call-template>
   </xsl:variable>
    /**
     * Get the pointer to the operational table copy of the parameter 
     * interpreted as a parameter of type <xsl:value-of select="$type"/>.
     * Run-time checks are performed on the legality of the parameter identifier
     * and on the correctness of the parameter type (i.e. it is verified that
     * the parameter being accessed is internally recorded as a parameter of 
     * type <xsl:value-of select="$type"/>). <xsl:text/>
   <xsl:choose>
     <xsl:when test="$level='1'">
     * Failure of the checks results in
     * the generation of an assert error. If assertions are disabled, the checks
     * are ineffective. 
     </xsl:when>
     <xsl:otherwise>
     * Failure of the checks results in
     * the generation of an assert error and in the generation of an event report
     * for an event of type EVT_ILLEGAL_DB_ACCESS. The method returns a default value 
     * zero.
     </xsl:otherwise>
   </xsl:choose> 
     <xsl:text/>* @param parId the identifier of the parameter to be set
     * @return the pointer to the parameter in the operational database
     */
    virtual <xsl:value-of select="$type"/>* getParameterPointer<xsl:value-of 
            select="$normalizedType"/>(TD_DatabaseId parId);
</xsl:template>

</xsl:stylesheet>

