//========================================================================= /// <summary> /// Find the init property item in the array. /// </summary> /// <param name="initName">Name of the init array.</param> /// <param name="idx">Array item index.</param> /// <returns>The typed value found at the index.</returns> //========================================================================= private TTypedValue findElementRead(string initName, int idx) { TTypedValue aValue = null; TTypedValue result; readValue(initName, ref aValue); if (aValue == null) { result = null; } else { if (!aValue.isArray()) { throw (new TypeMisMatchException("Attempt to read array from non-array value " + initName)); } if ((idx < 1) || (idx > aValue.count())) { throw (new ArrayIndexException("Attempt to read out of range of array value " + initName)); } result = aValue.item((uint)idx); } return(result); }
//========================================================================= /// <summary> /// Writes the srcValue to destValue. /// </summary> /// <param name="srcValue">The source value.</param> /// <param name="destValue">The destination item.</param> //========================================================================= private void writeData(TTypedValue srcValue, TTypedValue destValue) { uint Idx; if (destValue.isScalar()) { if (srcValue != null) { destValue.setValue(srcValue); } else if ((destValue.baseType() >= TTypedValue.TBaseType.ITYPE_INT1) && (destValue.baseType() <= TTypedValue.TBaseType.ITYPE_DOUBLE)) { destValue.setValue(0); } else { destValue.setValue(""); } } else if (destValue.isArray()) { if (srcValue == null) { destValue.setElementCount(0); } else { destValue.setElementCount(srcValue.count()); for (Idx = 1; Idx <= srcValue.count(); Idx++) { writeData(srcValue.item(Idx), destValue.item(Idx)); } } } else // record { for (Idx = 1; Idx <= destValue.count(); Idx++) { writeData(srcValue.member(destValue.item(Idx).Name), destValue.item(Idx)); } } }
//======================================================================= private void addTreeModelNode(TreeNode parentNode, String name, TTypedValue typedValue) { uint i = 1; uint j = 1; parentNode.Name = name; parentNode.Text = name; parentNode.Tag = new TAFTreeViewColumnTag(typedValue); if ((typedValue.isArray()) || (typedValue.isRecord())) { uint iCount = typedValue.count(); while (i <= iCount) { TTypedValue typedValueChild = typedValue.item(i); if (typedValueChild != null) { TreeNode trNode2 = new TreeNode(); parentNode.Nodes.Add(trNode2); string sVarName = j.ToString(); if (typedValue.isArray()) { sVarName = "[" + sVarName + "]"; } j++; if (typedValueChild.Name.Length > 0) { sVarName = typedValueChild.Name; } addTreeModelNode(trNode2, sVarName, typedValueChild); } i++; } } }
//============================================================================ /// <summary> /// Formats the xml text for the 'field' or 'element' description of the typed /// value stored as a TPropertyInfo or TDriverInfo. /// </summary> /// <param name="attrInfo">The TypedValue attribute.</param> /// <param name="indent">Indentation in chars.</param> /// <param name="tab">Number of spaces in each tab</param> /// <returns>XML text for the field</returns> //============================================================================ protected override String writeFieldInfo(TTypedValue attrInfo, int indent, int tab) { uint i; uint iFirst; 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"; } nextIndent = indent; String sIndent = new String(' ', startIndent + oneIndent); StringBuilder xml = new StringBuilder(""); 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 a scalar or array of scalars then write the defval|minval|maxval elements if (attrInfo.isScalar() || (attrInfo.isArray() && attrInfo.baseType() == TTypedValue.TBaseType.ITYPE_DEF)) { TInitValue initInfo = new TInitValue(attrInfo); if (initInfo != null) { if (initInfo.getDefault() != null) { xml.Append(sIndent + "<defval>" + initInfo.getDefault().asEscapedString() + "</defval>" + CR); } if (initInfo.getMin() != null) { xml.Append(sIndent + "<minval>" + initInfo.getMin().asEscapedString() + "</minval>" + CR); } if (initInfo.getMax() != null) { xml.Append(sIndent + "<maxval>" + initInfo.getMax().asEscapedString() + "</maxval>" + CR); } } } //now nest into the fields/elements sIndent = new String(' ', startIndent); if (!attrInfo.isScalar()) { // Special handling for non-scalar arrays of length 0, to ensure type definition is output iFirst = (uint)((attrInfo.isArray() && attrInfo.count() == 0) ? 0 : 1); for (i = iFirst; i <= attrInfo.count(); i++) { //for each child field if (attrInfo.isArray() && attrInfo.baseType() == TTypedValue.TBaseType.ITYPE_DEF) { xml.Append(sIndent + "<element"); xml.Append(writeFieldInfo(attrInfo.item(i), nextIndent, oneIndent)); xml.Append(sIndent + "</element>" + CR); } else if (attrInfo.isRecord()) { xml.Append(sIndent + "<field name=\"" + attrInfo.item(i).Name + "\""); xml.Append(writeFieldInfo(attrInfo.item(i), nextIndent, oneIndent)); xml.Append(sIndent + "</field>" + CR); } } } return(xml.ToString()); }
//============================================================================ /// <summary> /// Formats the xml text for the 'field' or 'element' description of the typed /// value stored as a TTypedValue. /// </summary> /// <param name="attrInfo"></param> /// <param name="indent"></param> /// <param name="tab">Number of spaces in each tab</param> /// <returns>Buffer containing the text</returns> /// N.Herrmann Apr 2002 //============================================================================ protected override String writeFieldInfo(TTypedValue attrInfo, int indent, int tab) { String elementType; uint i; int nextIndent; int oneIndent; String CR = ""; TTypedValue firstElement; String sIndent = ""; //determine how much to indent this description oneIndent = 0; nextIndent = -1; if (indent > -1) { CR = Environment.NewLine; oneIndent = tab; nextIndent = indent + oneIndent; sIndent = new String(' ', nextIndent); //begin at this level } StringBuilder xml = new StringBuilder(""); if (attrInfo.baseType() != 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() + "\""); } //now nest into the fields/elements for this DDML type if (!attrInfo.isScalar()) { xml.Append(">" + CR); if (attrInfo.isArray() && (attrInfo.baseType() == TBaseType.ITYPE_DEF)) //an array will only show the first child for DDML { if (attrInfo.count() == 0) { firstElement = attrInfo.item(0); } else { firstElement = attrInfo.item(1); } elementType = "element"; xml.Append(sIndent + "<" + elementType); xml.Append(writeFieldInfo(firstElement, nextIndent, oneIndent)); if (!firstElement.isScalar()) { xml.Append(sIndent + "</" + elementType + ">" + CR); } } else if (attrInfo.isRecord()) { for (i = 1; i <= attrInfo.count(); i++) //for each child field { elementType = "field"; xml.Append(sIndent + "<" + elementType + " name=\"" + attrInfo.item(i).Name + "\""); xml.Append(writeFieldInfo(attrInfo.item(i), nextIndent, oneIndent)); if (!attrInfo.item(i).isScalar()) { xml.Append(sIndent + "</" + elementType + ">" + CR); } } } } else { xml.Append("/>" + CR); } return(xml.ToString()); }
//============================================================================== /// <summary> /// Recursive logic for the AggregateValues routine /// For a scalar value, finds the corresponding output column and updates it. /// For an array or collection, recurses into each element or member. /// </summary> /// <param name="aValue"></param> /// <param name="aTree"></param> //============================================================================== private void aggregateValue(TTypedValue aValue, TValTree aTree) { int iColNo; int i; int oldLen; int parentId; if (aTree.varId < 0) { // Hasn't been defined yet... if (aTree.parent != null) { parentId = aTree.parent.varId; } else { parentId = -1; } aTree.varId = defineVariable(aTree.FullColumnName(), (TDDMLValue)aValue, parentId, (int)aTree.index, aTree.specifier); } if (aValue.isScalar()) // Scalar - we store or summarise the { // data if (aTree.colNo < 0) // Doesn't have a column number yet... { aTree.colNo = FColumns.Count; TOutputScalar aScalar = new TOutputScalar(aValue, aTree.specifier.Aggreg, aTree.specifier.iDecPl); aScalar.Name = aTree.FullColumnName(); FColumns.Add(aScalar); } iColNo = aTree.colNo; FColumns[iColNo].Update(aValue); } else // Array or collection - recurse { if (aValue.count() > aTree.subTrees.Count) { // Need to add new subTrees oldLen = aTree.subTrees.Count; //SetLength(aTree.subTrees, aValue.count()); for (i = oldLen; i < aValue.count(); i++) //for (i = oldLen; i <= aTree.subTrees.Count - 1; i++) { aTree.subTrees.Add(new TValTree(aTree, aTree.specifier)); aTree.subTrees[i].index = (uint)i + 1; if (aValue.isArray()) { aTree.subTrees[i].columnName = "[" + aTree.subTrees[i].index.ToString() + "]"; } else { if (aValue.isRecord()) { aTree.subTrees[i].columnName = ":" + aValue.item((uint)aTree.subTrees[i].index).Name; } } aTree.subTrees[i].varId = defineVariable(aTree.subTrees[i].FullColumnName(), (TDDMLValue)(aValue.item(aTree.subTrees[i].index)), aTree.varId, (int)aTree.subTrees[i].index, aTree.subTrees[i].specifier); } } for (i = 1; i <= aValue.count(); i++) { aggregateValue(aValue.item((uint)i), aTree.subTrees[i - 1]); } } }
//========================================================================== /// <summary> /// /// </summary> /// <param name="propertyID"></param> /// <param name="aValue"></param> //========================================================================== public override void initProperty(int propertyID, TTypedValue aValue) { String sText; uint Idx; TTypedValue varItem; if (!(FReporter is TStaticReporter) && (isWaterCastSim)) { FReporter = null; FReporter = new TStaticReporter(); } switch (propertyID) { case prpFILE: { FReporter.FileName = aValue.asString(); } break; case prpINTV: { FReporter.ReportInterval = aValue.asInteger(); } break; case prpUNIT: { sText = aValue.asString().ToLower().Trim(); for (int i = TTimeValue.SEC; i <= TTimeValue.YR; i++) { if (sText == TTimeValue.TIMETEXTS[i - 1]) { FReporter.IntervalUnit = i; } } } break; case prpOUTS: { for (Idx = 1; Idx <= aValue.count(); Idx++) { varItem = aValue.item(Idx); FReporter.addVariable(varItem.member("varname").asString(), varItem.member("alias").asString(), varItem.member("decplaces").asInteger(), FReporter.parseAggreg(varItem.member("aggreg").asString())); } } break; case prpSUMMARYFILE: { if (aValue.asString().Length == 0) { FSummaryStream = null; } else { FSummaryStream = new StreamWriter(aValue.asString()); addEvent("summaryFileWrite", evtSUMMARYWRITE, TypeSpec.KIND_SUBSCRIBEDEVENT, typeSUMMARYWRITE, "", "", 0); defineEventState(evtSUMMARYWRITE, stateDOWRITE, TStateMachine.NONLOGIC); defineEventTransition(evtSUMMARYWRITE, stateDOWRITE, 0, TStateMachine.DONE, false); } } break; case prpAPSIMFMT: { FReporter.ApsimFMT = aValue.asBool(); } break; case prpTITLE: { FReporter.Title = aValue.asStr(); } break; case prpOUTFREQ: { uint count = aValue.count(); for (uint i = 1; i <= count; i++) { //for each new event; add it to the list and also register it String eventName = aValue.item(i).asStr().ToLower(); if (!RegExtraEvents.ContainsValue(eventName)) { int eventId = evtEXTRAWRITE + RegExtraEvents.Count; addWritingEvent(eventId, eventName); RegExtraEvents.Add(eventId, eventName); } } } break; case prpDATEFMT: { FReporter.DateFMT = aValue.asStr(); } break; default: throw (new ApplicationException("Invalid ID code in initProperty()")); } if ((propertyID == prpFILE) || (propertyID == prpINTV) || //Store the initial value for later reading (propertyID == prpUNIT) || (propertyID == prpOUTS) || (propertyID == prpSUMMARYFILE)) { propertyList[propertyID].setValue(aValue); } }
//============================================================================ /// <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()); }