Пример #1
0
      //============================================================================
      /// <summary>
      /// Writes the SDML value as XML.
      /// </summary>
      /// <param name="attrInfo">The typed value to use.</param>
      /// <param name="indent">Indent spaces to use. -1 = no indent.</param>
      /// <param name="tab">Number of spaces in each tab</param>
      /// <returns>The XML for the SDML value.</returns>
      //============================================================================
       protected override String writeFieldInfo(TTypedValue attrInfo, int indent, int tab)
       {
           uint i;
           int oneIndent;
           int nextIndent;
           int startIndent;
           String CR = "";

           //determine how much to indent this description
           oneIndent = 0;
           startIndent = 0;
           if (indent > -1)
           {
               oneIndent = tab;
               startIndent = indent;
               CR = "\r\n";
           }
           String sIndent = new String(' ', startIndent);   //begin at this level
           nextIndent = indent + oneIndent;

           StringBuilder xml = new StringBuilder("");
           if (attrInfo.baseType() != TTypedValue.TBaseType.ITYPE_DEF)
               xml.Append(" kind=\"" + attrInfo.typeName() + "\"");
           if (attrInfo.isArray())
               xml.Append(" array=\"T\"");
           if ((attrInfo.units().Length > 0) && (attrInfo.units()[0] != '-'))
               xml.Append(" unit=\"" + attrInfo.units() + "\"");

           xml.Append(">" + CR);

           if (attrInfo.isScalar()) // Scalars - use a <val> element
           {
               xml.Append(sIndent + "<val>" + scalarString(attrInfo) + "</val>" + CR);
           }
           else
           {
               //now nest into the fields/elements
               for (i = 1; i <= attrInfo.count(); i++)
               {
                   if (attrInfo.isArray() && (attrInfo.baseType() != TTypedValue.TBaseType.ITYPE_DEF))
                   {
                       xml.Append(new String(' ', oneIndent) + "<val>" + scalarString(attrInfo.item(i)) + "</val>" + CR); // Scalar array, indented format
                   }
                   else if (attrInfo.isArray())                                          // All other arrays
                       xml.Append(sIndent + "<element"
                                   + writeFieldInfo(attrInfo.item(i), nextIndent, oneIndent)
                                   + sIndent + "</element>" + CR);
                   else if (attrInfo.isRecord())                                         // Records
                       xml.Append(sIndent + "<field name=\"" + attrInfo.item(i).Name + "\""
                                   + writeFieldInfo(attrInfo.item(i), nextIndent, oneIndent)
                                   + sIndent + "</field>" + CR);
               }
           }

           return xml.ToString();
       }
Пример #2
0
        //============================================================================
        /// <summary>
        /// Creates a 1-dimensional array of arbitrary type
        /// baseValue is used as a blue print only.
        /// </summary>
        /// <param name="arrayName">Name of the array.</param>
        /// <param name="baseValue">Blue print typed value.</param>
        /// <param name="noElements">Number of elements for the array.</param>
        //============================================================================
        public TTypedValue(String arrayName, TTypedValue baseValue, int noElements)
        {
            ascii = new System.Text.ASCIIEncoding();

            FMembers = new List<TTypedValue>();
            //set the kind of this typed value
            FBaseType = baseValue.FBaseType;

            parser = null;
            FData = null;
            FDataSize = 0;
            childTemplate = null;
            FUnit = "";
        }
Пример #3
0
 //============================================================================
 /// <summary>
 /// Copies data from one type to this type using the getData() setData() pair.
 /// Assumes that the source and destination are exactly compatible. Arrays will be
 /// resized as required.
 /// </summary>
 /// <param name="srcValue">The source value.</param>
 // adapted from A. Moore 2002
 //============================================================================
 public void copyFrom(TTypedValue srcValue)
 {
     if ((srcValue != null))
     {
         uint iSize = srcValue.sizeBytes();
         if (iSize > 0)
         {
             Byte[] data = new Byte[iSize];
             srcValue.getData(ref data);
             setData(data, (int)iSize, 0);
         }
     }
 }
Пример #4
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sTagDefinition"></param>
        /// <param name="aType"></param>
        protected void defineParameters(string sTagDefinition, TTypedValue.TBaseType aType)
        {
            string[] sDefn = new string[0];
            int Kdx;

            Tokenise(sTagDefinition, ref sDefn, "-");
            Kdx = FDefinitions.Length;
            Array.Resize(ref FDefinitions, Kdx + 1);
            FDefinitions[Kdx] = new TParameterDefinition(sDefn, aType);
        }
Пример #5
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="aValue"></param>
 /// <param name="Intake"></param>
 private void Value2IntakeRecord(TTypedValue aValue, ref GrazType.IntakeRecord Intake)
 {
     Intake.Biomass = aValue.item(1).asDouble();                         // Item[1]="dm"                          
     Intake.Digestibility = aValue.item(2).asDouble();                   // Item[2]="dmd"                         
     Intake.CrudeProtein = aValue.item(3).asDouble();                    // Item[3]="cp_conc"                     
     Intake.PhosContent = aValue.item(4).asDouble();                     // Item[4]="p_conc"                      
     Intake.SulfContent = aValue.item(5).asDouble();                     // Item[5]="s_conc"                      
     Intake.Degradability = aValue.item(6).asDouble();                   // Item[6]="prot_dg"                     
     Intake.AshAlkalinity = aValue.item(7).asDouble();                   // Item[7]="ashalk"                      
     Intake.HeightRatio = aValue.item(8).asDouble();                     // Item[8]="height_ratio"                
 }
Пример #6
0
      //============================================================================
      /// <summary>
      /// Gets the typed value as an XML description. &lt;init&gt; &lt;/init&gt;
      /// </summary>
      /// <param name="value">The typed value to describe as XML.</param>
      /// <param name="startIndent">Formatting indentation start.</param>
      /// <param name="tab">Number of spaces in each tab</param>
      /// <returns>The string buffer with the result.</returns>
      //============================================================================
      public override String getText(TTypedValue value, int startIndent, int tab)
      {
         int nextIndent;

         if (startIndent > -1)
            nextIndent = startIndent + tab;
         else
            nextIndent = -1;

         if (startIndent < 0)
            startIndent = 0;

         String sIndent= new String(' ', startIndent);

         StringBuilder sbuf = new StringBuilder(sIndent);
         sbuf.Append("<init name=\"");
         sbuf.Append(value.Name);
         sbuf.Append("\"");
         sbuf.Append(writeFieldInfo(value, nextIndent, tab));
         sbuf.Append(sIndent);
         sbuf.Append("</init>");

         return sbuf.ToString();
      }
Пример #7
0
 //============================================================================
 /// <summary>
 /// Copy constructor. This constructor makes a copy of the source's structure.
 /// For specialised child classes, this constructor should be overriden.
 /// </summary>
 /// <param name="typedValue">Use this as the blue print type.</param>
 //============================================================================
 public TSDMLValue(TTypedValue typedValue)
          : base (typedValue)
 {
    //required in this derived class
    initTypeCopy(typedValue);  //calls suitable virtual functions
 }
Пример #8
0
       //============================================================================
       /// <summary>
       /// Return the string for the scalar ttypedvalue.
       /// Numeric types are returned without any rounding or escaping.
       /// </summary>
       /// <param name="attrInfo">The scalar TTypedValue</param>
       /// <returns>String represenation of the scalar</returns>
       //============================================================================
       protected String scalarString(TTypedValue attrInfo)
       {
           String strVal;

           if ((attrInfo.baseType() >= TTypedValue.TBaseType.ITYPE_SINGLE) && (attrInfo.baseType() <= TTypedValue.TBaseType.ITYPE_DOUBLE))
           {
               strVal = attrInfo.asDouble().ToString(); //full precision
           }
           else
           {
               if ((attrInfo.baseType() >= TTypedValue.TBaseType.ITYPE_INT1) && (attrInfo.baseType() <= TTypedValue.TBaseType.ITYPE_INT8))
               {
                   strVal = attrInfo.asInt().ToString(); //no need to escape this   
               }
               else
               {
                   strVal = attrInfo.asEscapedString();
               }
           }
           return strVal;
       }
Пример #9
0
        //======================================================================
        /// <summary>
        /// Finds the type of this array object by recursing into the lower dimesions
        /// if needed.
        /// </summary>
        /// <param name="typedValue">The typed value to interogate.</param>
        /// <returns>The base type for this variable.  </returns>
        // N.Herrmann Apr 2002
        //======================================================================
        protected TBaseType findArrayType(TTypedValue typedValue)
        {
            TTypedValue value;
            TBaseType baseType;

            baseType = TBaseType.ITYPE_EMPTY; //default

            value = typedValue.item(1);  //first element
            if (value != null)
            {
                baseType = value.baseType();
                if (baseType == TBaseType.ITYPE_EMPTY)
                    baseType = findArrayType(value);
            }
            return baseType;
        }
Пример #10
0
        //======================================================================
        /// <summary>
        /// Assignment from a TTypedValue that need not be of identical type, but must   
        /// be type-compatible.
        /// When converting from a scalar string to a numeric an exception will be thrown
        /// if the source string is not a valid numeric.
        /// </summary>
        /// <param name="srcValue">The source typed value.</param>
        /// <returns>True is the value can be set.</returns>
        //======================================================================
        public Boolean setValue(TTypedValue srcValue)
        {
            bool result = false;
            bool bCompatible;

            if (srcValue != null)
            {
                bCompatible = ((FIsScalar == srcValue.isScalar()) && (FIsArray == srcValue.isArray()));
                if (FBaseType == TBaseType.ITYPE_DEF)
                {
                    bCompatible = (bCompatible && (srcValue.baseType() == TBaseType.ITYPE_DEF));
                }
                if (!bCompatible)
                {
                    String error = String.Format("Incompatible assignment from {0} to {1}\nCannot convert {2} to {3}", Name, srcValue.Name, srcValue.baseType().ToString(), FBaseType.ToString());
                    throw (new TypeMisMatchException(error));
                }
                if (FIsScalar)
                {
                    try
                    {
                        switch (FBaseType)
                        {
                            case TBaseType.ITYPE_INT1:
                            case TBaseType.ITYPE_INT2:
                            case TBaseType.ITYPE_INT4:
                                {
                                    result = setValue(srcValue.asInt());
                                    break;
                                }
                            case TBaseType.ITYPE_INT8:
                                result = setValue(Convert.ToInt64(srcValue.asDouble()));
                                break;
                            case TBaseType.ITYPE_DOUBLE:
                                {
                                    result = setValue(srcValue.asDouble());
                                    break;
                                }
                            case TBaseType.ITYPE_SINGLE:
                                {
                                    result = setValue(srcValue.asSingle());
                                    break;
                                }
                            case TBaseType.ITYPE_BOOL:
                                {
                                    result = setValue(srcValue.asBool());
                                    break;
                                }
                            default:
                                {
                                    result = setValue(srcValue.asStr());
                                    break;
                                }
                        }
                    }
                    catch
                    {
                        throw (new Exception("setValue() cannot convert " + srcValue.asStr() + " to " + FBaseType.ToString()));
                    }
                }
                else
                {
                    if (FIsArray)
                    {
                        setElementCount(srcValue.count());
                    }
                    uint iCount = count();
                    for (uint Idx = 1; Idx <= iCount; Idx++)
                    {
                        result = item(Idx).setValue(srcValue.item(Idx));
                    }
                }
            }
            return result;
        }
Пример #11
0
 //============================================================================
 /// <summary>
 /// For arrays, this will adjust the size of the FMembers list.
 /// </summary>
 /// <param name="dim">New dimension of this array.</param>
 // N.Herrmann Apr 2002
 //============================================================================
 public void setElementCount(uint dim)
 {
     if (FIsArray)
     {
         if (dim > FMembers.Count)
         {
             //add some more elements
             while (dim > FMembers.Count)
             {
                 //add a copy of the first element (structure)
                 if (FMembers.Count > 0)
                 {  //if there is an element to clone
                     newMember(item(1));      //Clones (copy constructor) the element structure
                 }
                 else
                 {
                     if (childTemplate != null)
                     {    //if previously stored an item that was removed when setElementCount(0)
                         addMember(childTemplate);
                         childTemplate = null; //now belongs to the list
                     }
                     else
                         addScalar("", FBaseType); //else determine what type the first element should be (must be a scalar)
                 }
             }
         }
         else if (dim < FMembers.Count)
         {
             while ((dim < FMembers.Count) && (FMembers.Count > 0))
             {
                 //delete some elements (newsize>=0)
                 deleteElement(FMembers.Count);  //1 based
             }
         }
     }
     else
         throw (new TypeMisMatchException("Cannot add or remove an array member to a non-array type."));
 }
Пример #12
0
 /// <summary>
 /// Add a new member.
 /// </summary>
 /// <param name="bluePrintValue"></param>
 public abstract void newMember(TTypedValue bluePrintValue);
Пример #13
0
 /// <summary>
 /// Text representation of a TTypedValue.
 /// </summary>
 /// <param name="value">The value</param>
 /// <param name="startIndent">Indent from here.</param>
 /// <param name="tab">Number of spaces in each tab</param>
 /// <returns>The XML.</returns>
 public abstract String getText(TTypedValue value, int startIndent, int tab);
Пример #14
0
        //============================================================================
        /// <summary>
        /// Tests for identity of two TTypedValue objects.
        /// </summary>
        /// <param name="otherValue">Typed value to test against this one.</param>
        /// <returns>True if it matches in type, size, and structure.</returns>
        // N.Herrmann Apr 2002
        //============================================================================
        public Boolean equals(TTypedValue otherValue)
        {
            uint i;
            Boolean bEqual = false;

            if ((otherValue != null) &&
               (FBaseType == otherValue.baseType()) &&
               (FIsArray == otherValue.isArray()) &&
               (FIsRecord == otherValue.isRecord()) &&
               (count() == otherValue.count()) &&
               (FDataSize == otherValue.sizeBytes()))
                bEqual = true;

            if (bEqual)
            {
                if (FIsScalar)
                    bEqual = bEqual && (asStr() == otherValue.asStr());    //str comparison of the scalar (needs refinement)
            }
            else
            {
                for (i = 1; i <= count(); i++)
                    bEqual = bEqual && item(i).equals(otherValue.item(i));
            }
            return bEqual;
        }
Пример #15
0
 //==============================================================================
 /// <summary>
 /// Delete an element from an array. Assumes that 'index' is the natural order
 /// of the items in the FMembers list.
 /// </summary>
 /// <param name="index">Array index 1->x</param>
 /// <returns></returns>
 // N.Herrmann Feb 2003
 //==============================================================================
 public void deleteElement(int index)
 {
     if (FIsArray)
     {
         if ((FMembers.Count > 0) && (FMembers.Count >= index))
         {
             //delete some elements (newsize>=0)
             if (FMembers.Count == 1)
                 childTemplate = FMembers[index - 1]; //store the last element locally for cloning later
             FMembers.RemoveAt(index - 1);   //delete it from the list
         }
     }
 }
Пример #16
0
        //============================================================================
        /// <summary>
        /// Copy constructor. This constructor makes a copy of the source's structure.
        /// For specialised child classes, this constructor should be overriden.
        /// </summary>
        /// <param name="typedValue">Use this typed value as the source.</param>
        // N.Herrmann Apr 2002
        //============================================================================
        public TTypedValue(TTypedValue typedValue)
        {
            ascii = new System.Text.ASCIIEncoding();

            FMembers = new List<TTypedValue>();
            //set the kind of this typed value
            FBaseType = typedValue.FBaseType;

            FData = null;
            FDataSize = 0;
            parser = null; //won't be using a parser here
            childTemplate = null;
            FUnit = "";

            //Called in the derived classes because it calls virtual functions
            //initTypeCopy(typedValue)
        }
Пример #17
0
 //============================================================================
 /// <summary>
 /// Only allowed to add members to records and arrays.
 /// </summary>
 /// <param name="newMember">The new member to add to this structure.</param>
 // N.Herrmann Apr 2002
 //============================================================================
 public void addMember(TTypedValue newMember)
 {
     if (((FIsArray || FIsRecord)) && (newMember != null))
     {
         if (FIsArray && ((FBaseType >= TBaseType.ITYPE_INT1) && (FBaseType <= TBaseType.ITYPE_DOUBLE))) //if number type
             newMember.setUnits(FUnit);
         FMembers.Add(newMember);
     }
 }
Пример #18
0
        //============================================================================
        /// <summary>
        /// The new member to add to this structure.
        /// </summary>
        /// <param name="typedValue">Typed value to copy.</param>
        // N.Herrmann Apr 2002
        //============================================================================
        protected void initTypeCopy(TTypedValue typedValue)
        {
            uint i;

            Name = typedValue.Name;
            FBaseType = typedValue.baseType();
            FIsScalar = typedValue.isScalar();
            FIsArray = typedValue.isArray();
            FIsRecord = typedValue.isRecord();
            setUnits(typedValue.units());

            if (FIsScalar)
            {
                createScalar();
                switch (FBaseType)
                {                                           //For scalars, copy the value data.
                    case TBaseType.ITYPE_INT1:                                            //Data pertaining to arrays and records
                    case TBaseType.ITYPE_INT2:                                            //   is ultimately stored in their
                    case TBaseType.ITYPE_INT4:                                            //   constituent scalars
                    case TBaseType.ITYPE_INT8: setValue(typedValue.asInt()); break;
                    case TBaseType.ITYPE_SINGLE: setValue(typedValue.asSingle()); break;
                    case TBaseType.ITYPE_DOUBLE: setValue(typedValue.asDouble()); break;
                    case TBaseType.ITYPE_BOOL: setValue(typedValue.asBool()); break;
                    case TBaseType.ITYPE_CHAR:
                    case TBaseType.ITYPE_WCHAR: setValue(typedValue.asChar()); break;
                    case TBaseType.ITYPE_STR:
                    case TBaseType.ITYPE_WSTR: setValue(typedValue.asStr()); break;
                }
            }
            else if (FIsArray || FIsRecord)
            {
                uint iCount = typedValue.count();
                if (FIsArray && (iCount == 0))
                {
                    if (typedValue.item(0) != null)
                        newMember(typedValue.item(0));
                    setElementCount(0);
                }
                else
                    for (i = 1; i <= iCount; i++)
                        newMember(typedValue.item(i)); //clones and adds this typed value
            }
        }
Пример #19
0
 //============================================================================
 /// <summary>
 /// Creates a one dimensional array of arbitrary items.
 /// </summary>
 /// <param name="sArrayName">Name of this array.</param>
 /// <param name="baseValue">Use as the base type of the array elements.</param>
 /// <param name="iNoElements">Create it with this number of elements.</param>
 //============================================================================
 public TSDMLValue(String sArrayName, TTypedValue baseValue, int iNoElements)
          : base (sArrayName, baseValue, iNoElements)
 {
    newMember( baseValue );
    setElementCount((uint)iNoElements);
 }
Пример #20
0
 /// <summary>
 /// Writes a field as a string
 /// </summary>
 /// <param name="attrInfo">The value</param>
 /// <param name="indent">Indentation 0-n</param>
 /// <param name="tab">Number of spaces in each tab</param>
 /// <returns>The XML for the typed value.</returns>
 protected abstract String writeFieldInfo(TTypedValue attrInfo, int indent, int tab);
Пример #21
0
      //============================================================================
      /// <summary>
      /// Uses the copy constructor to make a clone of a typedvalue's structure.
      /// It is then added as a member to an array or record.
      /// this virtual function is expected to be overriden so that new members are
      /// of the child classes' type.
      /// </summary>
      /// <param name="bluePrintValue">Use this typed value as the blue print.</param>
      //============================================================================
      public override void newMember(TTypedValue bluePrintValue)
      {
         TSDMLValue newElement;

         newElement = new TSDMLValue(bluePrintValue); //calls copy constructor
         addMember(newElement);  //add the copy
      }
Пример #22
0
 //============================================================================
 /// <summary>
 /// Constructor that will show details of the two types causing the problem.
 /// </summary>
 /// <param name="first">First TTypedValue.</param>
 /// <param name="second">Second TTypedValue.</param>
 //============================================================================
 public TypeMisMatchException(TTypedValue first, TTypedValue second)
     : base("Type mismatch exception: " + first.typeName() + " does not match " + second.typeName())
 {
 }
Пример #23
0
        //============================================================================
        /// <summary>
        /// Construct this object using the parser already created in the parent. Also
        /// use the dom node, baseNode to be the root node of the document for this
        /// new typed value. Can also specify the base type using sBaseType.
        /// </summary>
        /// <param name="parentParser">Pointer to the parents parser.</param>
        /// <param name="baseNode">DOM node to use as the root node.</param>
        /// <param name="sBaseType">Used to set the base type.  See <see cref="sTYPECODES"/></param>
        // N.Herrmann Apr 2002
        //============================================================================
        public TTypedValue(TSDMLParser parentParser, XmlNode baseNode, String sBaseType)
        {
            ascii = new System.Text.ASCIIEncoding();

            FMembers = new List<TTypedValue>();
            //set the kind of this typed value
            setBaseType(sBaseType);

            parser = null;
            FData = null;
            FDataSize = 0;
            childTemplate = null;
            FUnit = "";

            //Called in the derived classes because it calls virtual functions
            //buildType(parentParser, baseNode);
        }
Пример #24
0
        //============================================================================
        /// <summary>
        /// Creates a scalar of this aBaseType with sName.
        /// </summary>
        /// <param name="sName">Name of the scalar.</param>
        /// <param name="aBaseType">Base type of this scalar.</param>
        // N.Herrmann Apr 2002
        //============================================================================
        public TTypedValue(String sName, TBaseType aBaseType)
        {
            ascii = new System.Text.ASCIIEncoding();

            FMembers = new List<TTypedValue>();
            //set the kind of this typed value
            FBaseType = aBaseType;
            //Called in the derived classes because it calls virtual functions
            //constructScalar(szName, iBaseType);  //create a scalar type of TTypedValue
            parser = null;
            childTemplate = null;
            FUnit = "";
        }
Пример #25
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="aValue"></param>
        /// <returns></returns>
        private GrazType.TGrazingInputs Value2GrazingInputs(TTypedValue aValue)
        {
            double fTotalDM;
            int Idx;

            GrazType.TGrazingInputs Result = new GrazType.TGrazingInputs();
            GrazType.zeroGrazingInputs(ref Result);

            for (Idx = 1; Idx <= Math.Min(GrazType.DigClassNo, aValue.item(1).count()); Idx++)      // Item[1]="herbage"                     
                Value2IntakeRecord(aValue.item(1).item((uint)Idx), ref Result.Herbage[Idx]);

            fTotalDM = 0.0;
            for (Idx = 1; Idx <= GrazType.DigClassNo; Idx++)
                fTotalDM = fTotalDM + Result.Herbage[Idx].Biomass;
            Result.TotalGreen = fTotalDM * aValue.item(2).asDouble();                               // Item[2]="propn_green"                 
            Result.TotalDead = fTotalDM - Result.TotalGreen;

            Result.LegumePropn = aValue.item(3).asDouble();                                         // Item[3]="legume"                      
            Result.SelectFactor = aValue.item(4).asDouble();                                        // Item[4]="select_factor"               

            for (Idx = 1; Idx <= Math.Min(2, aValue.item(5).count()); Idx++)                        // Item[5]="seed"                        
            {
                Value2IntakeRecord(aValue.item(5).item((uint)Idx), ref Result.Seeds[1, Idx]);
                Result.SeedClass[1, Idx] = aValue.item(6).item((uint)Idx).asInteger();              // Item[6]="seed_class"                  
            }
            return Result;
        }
Пример #26
0
        //============================================================================
        /// <summary>
        /// Creates a one dimensional array of scalar items.
        /// </summary>
        /// <param name="sArrayName">Name of this array.</param>
        /// <param name="aBaseType">Set the base type of this array.</param>
        /// <param name="iNoElements">Create it with this number of elements.</param>
        // N.Herrmann Apr 2002
        //============================================================================
        public TTypedValue(String sArrayName, TBaseType aBaseType, int iNoElements)
        {
            ascii = new System.Text.ASCIIEncoding();

            FMembers = new List<TTypedValue>();
            //set the kind of this typed value
            FBaseType = aBaseType;

            parser = null;
            FData = null;
            FDataSize = 0;
            childTemplate = null;

            Name = sArrayName;
            FUnit = "";
            FIsScalar = false;
            FIsArray = true;
            FIsRecord = false;

            //Called in the derived classes because they call virtual functions
            //addScalar("", iBaseType);     //calls suitable virtual function
            //setElementCount(iNoElements);
        }
Пример #27
0
        /// <summary>
        /// Each element of a "definition string" array may take one of two forms:       
        /// * val:val        Integer subrange (e.g. "1:8")                              
        /// * text[;text]*   List of text indices                                       
        ///                                                                             
        /// For example, if the original string from which sDefnStrings was constructed  
        /// was "KQ-1:4-leaf;stem", then the resulting tree of definitions would be:     
        /// KQ                                                                         
        ///  |                                                                         
        ///  +-+-------------+-------------+-------------+                             
        ///    |             |             |             |                             
        ///    1             2             3             4                             
        ///    +-+-----+     +-+-----+     +-+-----+     +-+-----+                     
        ///      |     |       |     |       |     |       |     |                     
        ///      leaf  stem    leaf  stem    leaf  stem    leaf  stem                  
        /// </summary>
        /// <param name="sDefnStrings"></param>
        /// <param name="aType"></param>
        /// <param name="iOffset"></param>
        public TParameterDefinition(string[] sDefnStrings, TTypedValue.TBaseType aType, int iOffset = 0)
        {
            FItems = new TParameterDefinition[0];
            string[] sSubDefnStrings = new string[0];
            string sIndexStr;
            int iPosn;
            int Idx;

            FName = sDefnStrings[0];
            for (Idx = 1; Idx <= iOffset; Idx++)
                FName = FName + "-" + sDefnStrings[Idx];
            if (iOffset < (sDefnStrings.Length - 1))
                FName = FName + "-";
            FName = FName.ToLower();

            FNamePart = sDefnStrings[iOffset].ToLower();
            FType = aType;
            FDefined = false;

            if (iOffset < (sDefnStrings.Length - 1))
            {
                Array.Resize(ref sSubDefnStrings, sDefnStrings.Length);
                for (Idx = 0; Idx <= (sSubDefnStrings.Length - 1); Idx++)
                    sSubDefnStrings[Idx] = sDefnStrings[Idx];
                sIndexStr = sDefnStrings[iOffset + 1];

                iPosn = sIndexStr.IndexOf(':');
                if (iPosn >= 0)                                                        // Integer subrange
                {
                    int start = Convert.ToInt32(sIndexStr.Substring(0, iPosn));
                    int endpos = Convert.ToInt32(sIndexStr.Substring(iPosn + 1, sIndexStr.Length - iPosn - 1));
                    for (Idx = start; Idx <= endpos; Idx++)
                    {
                        sSubDefnStrings[iOffset + 1] = Convert.ToString(Idx);
                        Array.Resize(ref FItems, FItems.Length + 1);
                        FItems[FItems.Length - 1] = new TParameterDefinition(sSubDefnStrings, aType, iOffset + 1);
                    }
                }
                else                                                                       // Single index or semi-colon-separated  }
                {                                                                      //   list of indices                     }
                    while (sIndexStr != "")
                    {
                        iPosn = sIndexStr.IndexOf(";");
                        if (iPosn >= 0)
                        {
                            sSubDefnStrings[iOffset + 1] = sIndexStr.Substring(0, iPosn);
                            sIndexStr = sIndexStr.Substring(iPosn + 1, sIndexStr.Length - iPosn - 1);
                        }
                        else
                        {
                            sSubDefnStrings[iOffset + 1] = sIndexStr;
                            sIndexStr = "";
                        }

                        Array.Resize(ref FItems, FItems.Length + 1);
                        FItems[FItems.Length - 1] = new TParameterDefinition(sSubDefnStrings, aType, iOffset + 1);
                    }
                }
            }

            FCount = FItems.Length;
            if (bIsScalar())
                FParamCount = 1;
            else
                FParamCount = FCount * item(0).iParamCount;
        }
Пример #28
0
        //============================================================================
        /// <summary>
        /// Recursive routine for checking whether two types are (a) identical,
        /// (b) different but compatible, (c) incompatible.
        /// <para>Note:</para>
        /// <para>1. Type compatibility is not a transitive relationship.</para>
        /// <para>2. Unit compatibility needs further implementation.</para>
        /// </summary>
        /// <param name="srcValue">The TTypedValue to compare with.</param>
        /// <returns>Returns: 0 - exact match, 1 - compatible, -1 - cannot match</returns>
        //============================================================================
        public int canAssignFrom(TTypedValue srcValue)
        {
            int result = ctBAD;
            uint Idx;

            if (srcValue.isScalar())
            {
                if (!FIsScalar)
                    result = ctBAD;
                else if (srcValue.baseType() == FBaseType)
                    result = ctSAME;
                else if ((srcValue.baseType() <= TBaseType.ITYPE_INT8) && (srcValue.baseType() >= TBaseType.ITYPE_INT1) &&
                         (FBaseType <= TBaseType.ITYPE_INT8) && (FBaseType >= TBaseType.ITYPE_INT1))
                    result = ctCOMP;  //both integers
                else if ((FBaseType >= TBaseType.ITYPE_SINGLE) && (FBaseType <= TBaseType.ITYPE_DOUBLE) &&           //These conditions are not transitive
                         (srcValue.baseType() >= TBaseType.ITYPE_INT1) && (srcValue.baseType() <= TBaseType.ITYPE_DOUBLE))
                    result = ctCOMP;  //can match an int/single source to single/double destination
                else if ((srcValue.baseType() == TBaseType.ITYPE_CHAR) &&
                    ((FBaseType == TBaseType.ITYPE_WCHAR) ||
                    (FBaseType == TBaseType.ITYPE_STR) ||
                    (FBaseType == TBaseType.ITYPE_WSTR)))
                    result = ctCOMP;
                else if ((srcValue.baseType() == TBaseType.ITYPE_WCHAR) && (FBaseType == TBaseType.ITYPE_WSTR))
                    result = ctCOMP;
                else if ((srcValue.baseType() == TBaseType.ITYPE_STR) && (FBaseType == TBaseType.ITYPE_WSTR))
                    result = ctCOMP;
                // A sop to the old APSIM manager, which sends out all request-set values as strings
                else if ((srcValue.baseType() == TBaseType.ITYPE_STR) || (FBaseType == TBaseType.ITYPE_WSTR))
                    result = ctDODGY;
                else
                    result = ctBAD;

                if ((FBaseType >= TBaseType.ITYPE_INT1) && (FBaseType <= TBaseType.ITYPE_DOUBLE) &&
                      (!unitsMatch(units(), srcValue.units())))
                    result = ctBAD;
            }
            else if (srcValue.isArray())
            {   //an array
                if (!FIsArray)
                    result = ctBAD;
                else
                {
                    if (count() == 0)
                        setElementCount(1);  //addElement();
                    if (srcValue.count() == 0)
                        srcValue.setElementCount(1); //addElement();
                    result = member(1).canAssignFrom(srcValue.member(1));
                }
            }
            else
            {   //a record
                if (!isRecord())
                    result = ctBAD;
                else
                {
                    uint iCount = count();
                    result = ctCOMP;                                                        // First, test for identity
                    if (iCount == srcValue.count())
                    {
                        result = ctSAME;
                        for (Idx = 1; Idx <= iCount; Idx++)
                        {
                            if ((member(Idx).Name.ToLower() != srcValue.member(Idx).Name.ToLower()) ||
                                  (member(Idx).canAssignFrom(srcValue.member(Idx)) != ctSAME))
                                result = ctCOMP;
                        }
                    }

                    if (result == ctCOMP)
                    {                                                //If not same, test for compatibility
                        String elemName;
                        for (Idx = 1; Idx <= srcValue.count(); Idx++)
                        {
                            elemName = srcValue.member(Idx).Name;                 //field name
                            if (!hasField(elemName) ||
                                  (member(elemName).canAssignFrom(srcValue.member(Idx)) == ctBAD))
                                result = ctBAD;
                        }
                    }
                }
            }

            return result;
        }