/// <summary>Initializes a new type definition.</summary> /// <param name="parent">The <see cref="VarCollection"/> that contains the item, should always be <see cref="Types"/>.</param> /// <param name="name">The name of the type.</param> /// <param name="count">The total number of items in the definition.</param> /// <param name="id">The ID number to be used with dynamics.</param> /// <exception cref="ArgumentNullException"><i>name</i>, <i>count</i> or <i>id</i> are <b>null</b> or empty.</exception> /// <exception cref="ArgumentException"><i>count</i> is not a constant.</exception> /// <remarks>Values is *not* populated, only the initial Capacity is set</remarks> public DefinitionVar(VarCollection parent, string name, string count, string id) { if (name == "" || name == null || id == "" || id == null || count == "" || count == null) { throw new ArgumentNullException("Definition elements require 'name', 'id' and 'count' attributes", ((name == "" || name == null) ? "name" : ((id == "" || id == null)? "id" : "count"))); } if (isDynamicText(count) || Equation.Evaluate(count) != count) { throw new ArgumentException("'count' attribute must be constant", "count"); } _parent = parent; _type = VarType.Definition; bool loading = _parent.isLoading; _parent.isLoading = true; Name = name; try { Values = new VarCollection(this, int.Parse(count)); } catch (FormatException x) { throw new FormatException("'count' is not a valid integer", x); } catch (OverflowException x) { throw new ArgumentOutOfRangeException("'count' must be between zero and " + int.MaxValue, x); } try { _id = int.Parse(id); } catch (FormatException x) { throw new FormatException("'id' is not a valid integer", x); } catch (OverflowException x) { throw new OverflowException("'id' must be lower than " + int.MaxValue, x); } _parent.isLoading = loading; }
/// <summary>Re-initialize the contents of the Collection using raw byte data.</summary> /// <param name="rawData">Raw byte data from file.</param> /// <param name="startingOffset">Offset within <i>rawData</i> to begin reading.</param> /// <returns>First offset following the collection data.</returns> public int Populate(byte[] rawData, int startingOffset) { //System.Diagnostics.Debug.WriteLine("pop, " + startingOffset); bool loading = _isLoading; _isLoading = true; int id = -1; int count = Count; int pos = startingOffset; Var definition = null; if (parentVar != null && parentVar.Type == VarType.Collection) { id = parentVar.ID; definition = parentFile.Types.GetItemByID(id); count = definition.Quantity; } for (int i = 0; i < count; i++) { if (id != -1) { //System.Diagnostics.Debug.WriteLine(definition[i].Type.ToString()); if (definition[i].Type == VarType.Bool) { Add((BoolVar)definition[i].DeepCopy()); } else if (definition[i].Type == VarType.Byte) { Add((ByteVar)definition[i].DeepCopy()); } else if (definition[i].Type == VarType.Collection) { Add((CollectionVar)definition[i].DeepCopy()); } else if (definition[i].Type == VarType.Double) { Add((DoubleVar)definition[i].DeepCopy()); } else if (definition[i].Type == VarType.Int) { Add((IntVar)definition[i].DeepCopy()); } else if (definition[i].Type == VarType.Long) { Add((LongVar)definition[i].DeepCopy()); } else if (definition[i].Type == VarType.SByte) { Add((SByteVar)definition[i].DeepCopy()); } else if (definition[i].Type == VarType.Short) { Add((ShortVar)definition[i].DeepCopy()); } else if (definition[i].Type == VarType.Single) { Add((SingleVar)definition[i].DeepCopy()); } else if (definition[i].Type == VarType.String) { Add((StringVar)definition[i].DeepCopy()); } else if (definition[i].Type == VarType.UInt) { Add((UIntVar)definition[i].DeepCopy()); } else if (definition[i].Type == VarType.ULong) { Add((ULongVar)definition[i].DeepCopy()); } else if (definition[i].Type == VarType.UShort) { Add((UShortVar)definition[i].DeepCopy()); } else { Add((Var)definition[i].DeepCopy()); } } if (this[i].IsPresent) { if (this[i].RawOffset != "-1") { pos = startingOffset + this[i].LocalOffset; } if (this[i].Quantity != 0) { this[i].Values.isLoading = true; } switch (this[i].Type) { case VarType.Bool: if (this[i].Quantity == 0) { this[i].RawValue = rawData[pos]; } else { for (int j = 0; j < this[i].Quantity; i++) { this[i].Values.Add(VarType.Bool); this[i][j].RawValue = rawData[pos++]; } } break; case VarType.Byte: if (this[i].Quantity == 0) { ((ByteVar)this[i]).Value = rawData[pos]; } else { for (int j = 0; j < this[i].Quantity; j++) { this[i].Values.Add(VarType.Byte); ((ByteVar)this[i][j]).Value = rawData[pos++]; } } break; case VarType.Collection: for (int j = 0; j < this[i].Quantity; j++) { this[i].Values.Add(new CollectionVar(this[i].Values, this[i].ID)); this[i][j].Values = new VarCollection(this[i][j]); pos = this[i][j].Values.Populate(rawData, pos); } break; case VarType.Double: if (this[i].Quantity == 0) { this[i].RawValue = BitConverter.ToDouble(rawData, pos); } else { for (int j = 0; j < this[i].Quantity; j++) { this[i].Values.Add(VarType.Double); this[i][j].RawValue = BitConverter.ToDouble(rawData, pos); pos += 8; } } break; case VarType.Int: if (this[i].Quantity == 0) { this[i].RawValue = BitConverter.ToInt32(rawData, pos); } else { for (int j = 0; j < this[i].Quantity; j++) { this[i].Values.Add(VarType.Int); this[i][j].RawValue = BitConverter.ToInt32(rawData, pos); pos += 4; } } break; case VarType.Long: if (this[i].Quantity == 0) { this[i].RawValue = BitConverter.ToInt64(rawData, pos); } else { for (int j = 0; j < this[i].Quantity; j++) { this[i].Values.Add(VarType.Long); this[i][j].RawValue = BitConverter.ToInt64(rawData, pos); pos += 8; } } break; case VarType.SByte: if (this[i].Quantity == 0) { this[i].RawValue = (sbyte)rawData[pos]; } else { for (int j = 0; j < this[i].Quantity; j++) { this[i].Values.Add(VarType.SByte); this[i][j].RawValue = (sbyte)rawData[pos++]; } } break; case VarType.Short: if (this[i].Quantity == 0) { this[i].RawValue = BitConverter.ToInt16(rawData, pos); } else { for (int j = 0; j < this[i].Quantity; j++) { this[i].Values.Add(VarType.Short); this[i][j].RawValue = BitConverter.ToInt16(rawData, pos); pos += 2; } } break; case VarType.Single: if (this[i].Quantity == 0) { this[i].RawValue = BitConverter.ToSingle(rawData, pos); } else { for (int j = 0; j < this[i].Quantity; j++) { this[i].Values.Add(VarType.Single); this[i][j].RawValue = BitConverter.ToSingle(rawData, pos); pos += 4; } } break; case VarType.String: int stringLength = int.Parse(Equation.Evaluate(ParseDynamicValues(this, this[i].RawLength))); Encoding enc = ((StringVar)this[i]).Encoding; if (this[i].Quantity == 0 && stringLength != 0) { this[i].RawValue = enc.GetString(rawData, pos, stringLength); } else if (this[i].Quantity != 0) { for (int j = 0; j < this[i].Quantity; j++) { this[i].Values.Add(VarType.String); if (this[i].RawLength != "0") { this[i][j].RawValue = enc.GetString(rawData, pos, stringLength); } pos += stringLength; } } break; case VarType.UInt: if (this[i].Quantity == 0) { this[i].RawValue = BitConverter.ToUInt32(rawData, pos); } else { for (int j = 0; j < this[i].Quantity; j++) { this[i].Values.Add(VarType.UInt); this[i][j].RawValue = BitConverter.ToUInt32(rawData, pos); pos += 4; } } break; case VarType.ULong: if (this[i].Quantity == 0) { this[i].RawValue = BitConverter.ToUInt64(rawData, pos); } else { for (int j = 0; j < this[i].Quantity; j++) { this[i].Values.Add(VarType.ULong); this[i][j].RawValue = BitConverter.ToUInt64(rawData, pos); pos += 8; } } break; case VarType.UShort: if (this[i].Quantity == 0) { this[i].RawValue = BitConverter.ToUInt16(rawData, pos); } else { for (int j = 0; j < this[i].Quantity; j++) { this[i].Values.Add(VarType.UShort); this[i][j].RawValue = BitConverter.ToUInt16(rawData, pos); pos += 2; } } break; } if (this[i].Quantity != 0) { for (int n = 0; n < this[i].Quantity; n++) { if (this[i].Values._names != null) { try { this[i][n].Name = this[i].Values._names[n]; } catch { this[i][n].Name = n.ToString(); System.Diagnostics.Debug.WriteLine("Names count mismatch: " + this[i].ToString() + "[" + n + "]"); } } else { this[i][n].Name = n.ToString(); } } this[i].Values.isLoading = false; } else { pos += this[i].Length; } } } //System.Diagnostics.Debug.WriteLine("copied"); if (definition != null && definition.RawLength != "-1") { pos = startingOffset + int.Parse(definition.RawLength); } _isLoading = loading; return(pos); }
/// <exception cref="ArgumentException">Bracket mismatch<br/><b>-or-</b><br/>Empty term</exception> static string calculate(string cond) { if (cond == "") { throw new ArgumentException("Empty term found"); } if (cond.IndexOf("(") != -1) { int leftIndex = cond.LastIndexOf("("); int rightIndex = cond.IndexOf(")", leftIndex); if (rightIndex == -1) { throw new ArgumentException("Bracket mismatch, closing bracket not found"); } return(calculate(cond.Substring(0, leftIndex) + calculate(cond.Substring(leftIndex + 1, rightIndex - leftIndex - 1)) + cond.Substring(rightIndex + 1))); } else if (cond.IndexOf(")") != -1) { throw new ArgumentException("Bracket mismatch, opening bracket not found"); } string left, right; if (cond.IndexOf("&&") != -1) { left = calculate(cond.Substring(0, cond.IndexOf("&&"))); right = calculate(cond.Substring(cond.IndexOf("&&") + 2)); return((left == "T") && (right == "T") ? "T" : "F"); } else if (cond.IndexOf("||") != -1) { left = calculate(cond.Substring(0, cond.IndexOf("||"))); right = calculate(cond.Substring(cond.IndexOf("||") + 2)); return((left == "T") || (right == "T") ? "T" : "F"); } else if (cond.IndexOf("==") != -1) { left = calculate(cond.Substring(0, cond.IndexOf("=="))); right = calculate(cond.Substring(cond.IndexOf("==") + 2)); return(left == right ? "T" : "F"); } else if (cond.IndexOf("!=") != -1) { left = calculate(cond.Substring(0, cond.IndexOf("!="))); right = calculate(cond.Substring(cond.IndexOf("!=") + 2)); return(left != right ? "T" : "F"); } else if (cond.IndexOf(">=") != -1) { left = calculate(cond.Substring(0, cond.IndexOf(">="))); right = calculate(cond.Substring(cond.IndexOf(">=") + 2)); return(double.Parse(left) >= double.Parse(right) ? "T" : "F"); } else if (cond.IndexOf("<=") != -1) { left = calculate(cond.Substring(0, cond.IndexOf("<="))); right = calculate(cond.Substring(cond.IndexOf("<=") + 2)); return(double.Parse(left) <= double.Parse(right) ? "T" : "F"); } else if (cond.IndexOf("<") != -1 && cond.IndexOf("<<") == -1) { left = calculate(cond.Substring(0, cond.IndexOf("<"))); right = calculate(cond.Substring(cond.IndexOf("<") + 1)); return(double.Parse(left) < double.Parse(right) ? "T" : "F"); } else if (cond.IndexOf(">") != -1 && cond.IndexOf(">>") == -1) { left = calculate(cond.Substring(0, cond.IndexOf(">"))); right = calculate(cond.Substring(cond.IndexOf(">") + 1)); return(double.Parse(left) > double.Parse(right) ? "T" : "F"); } if (cond.IndexOf("<<") != -1) { string section = cond; int offset = 0; for (; offset < cond.Length;) { int shiftIndex = section.IndexOf("<<"); int compareIndex = section.IndexOf("<"); if (compareIndex == -1) { // '<' does not exist by itself break; } else if (compareIndex == shiftIndex) { // skip over "<<" offset += shiftIndex + 2; section = cond.Substring(offset); continue; } else { // found a stand-alone '<' offset += compareIndex; left = calculate(cond.Substring(0, offset)); right = calculate(cond.Substring(offset + 1)); return(double.Parse(left) < double.Parse(right) ? "T" : "F"); } } } if (cond.IndexOf(">>") != -1) { string section = cond; for (int offset = 0; offset < cond.Length;) { int shiftIndex = section.IndexOf(">>"); int compareIndex = section.IndexOf(">"); if (compareIndex == -1) { // '>' does not exist by itself break; } else if (compareIndex == shiftIndex) { // skip over ">>" offset += shiftIndex + 2; section = cond.Substring(offset); continue; } else { // found a stand-alone '>' offset += compareIndex; left = calculate(cond.Substring(0, offset)); right = calculate(cond.Substring(offset + 1)); return(double.Parse(left) > double.Parse(right) ? "T" : "F"); } } } if (cond == "T" || cond == "F") { return(cond); } else { return(Equation.Evaluate(cond)); } }