/// <summary> /// Reads a value in radians. /// </summary> /// <param name="field">A tag associated with the value</param> /// <returns>The radian value that was read.</returns> internal RadianValue ReadRadians(DataField field) { string s = m_Reader.ReadString(field.ToString()); double d = RadianValue.Parse(s); return(new RadianValue(d)); }
/// <summary> /// Write a value in radians to a storage medium. /// </summary> /// <param name="field">The tag that identifies the item.</param> /// <param name="value">The radian value to write</param> internal void WriteRadians(DataField field, RadianValue value) { m_Writer.WriteString(field.ToString(), value.AsShortString()); }
void ParseWord(string str) { // Return if string is empty (could be empty if this function // has been called recursively from below). str = str.Trim(); int nc = str.Length; if (nc == 0) { return; } // If we have a new default units specification, make it // the default. There should be whitespace after the "..." if (str.Contains("...")) { DistanceUnit unit = GetUnits(str, true); PathItem item = new PathItem(PathItemType.Units, unit, 0.0); AddItem(item); return; } // If we have a counter-clockwise indicator, just remember it // and parse anything that comes after it. if (nc >= 2 && String.Compare(str.Substring(0, 2), "cc", true) == 0) { AddItem(PathItemType.CounterClockwise); ParseWord(str.Substring(2)); return; } // If we have a BC, remember it & parse anything that follows. if (str[0] == '(') { AddItem(PathItemType.BC); ParseWord(str.Substring(1)); return; } // If we have a EC, remember it & parse anything that follows. if (str[0] == ')') { AddItem(PathItemType.EC); ParseWord(str.Substring(1)); return; } // If we have a single slash character (possibly followed by // a digit or a decimal point), record the single slash & // parse anything that follows. if (str[0] == '/') { // Check for a free-standing slash, or a slash that is // followed by a numeric digit or decimal point. if (nc == 1 || Char.IsDigit(str, 1) || str[1] == '.') { AddItem(PathItemType.Slash); ParseWord(str.Substring(1)); return; } // More than one character, or what follows is not a digit. // So we are dealing with either a miss-connect, or an // omit-point. In either case, there should be whitespace // after that. if (nc == 2) { if (str[1] == '-') { AddItem(PathItemType.MissConnect); return; } if (str[1] == '*') { AddItem(PathItemType.OmitPoint); return; } } // Allow CADCOR-style data entry else if (nc == 3) { if (String.Compare(str, "/mc", true) == 0) { AddItem(PathItemType.MissConnect); return; } if (String.Compare(str, "/op", true) == 0) { AddItem(PathItemType.OmitPoint); return; } } string msg = String.Format("Unexpected qualifier '{0}'", str); throw new ApplicationException(msg); } // If we have a multiplier, it must be immediately followed // by a numeric (integer) value. if (str[0] == '*') { if (nc == 1) { throw new ApplicationException("Unexpected '*' character"); } // Pick up the repeat count (not sure if the digits need to be // followed by white space, or whether non-numeric digits are valid, // so pick up only the digits). string num = GetIntDigits(str.Substring(1)); // Error if repeat count is less than 2. int repeat; if (!Int32.TryParse(num, out repeat) || repeat < 2) { string msg = String.Format("Unexpected repeat count in '{0}'", str); throw new ApplicationException(msg); } if (repeat < 2) { string msg = String.Format("Unexpected repeat count in '{0}'", str); throw new ApplicationException(msg); } // Duplicate the last item using the repeat count. AddRepeats(repeat); // Continue parsing after the repeat count. ParseWord(str.Substring(1 + num.Length)); return; } // If the string contains an embedded qualifier (a "*" or a "/" // character), process the portion of any string prior to the // qualifier. Note that we have just handled the cases where // the qualifier was at the very start of the string. int starIndex = str.IndexOf('*'); int slashIndex = str.IndexOf('/'); if (starIndex >= 0 || slashIndex >= 0) { int qualIndex = starIndex; if (qualIndex < 0 || (slashIndex >= 0 && qualIndex > slashIndex)) { qualIndex = slashIndex; } // Process the stuff prior to the qualifier. string copy = str.Substring(0, qualIndex); ParseWord(copy); // Process the stuff, starting with the qualifier character ParseWord(str.Substring(qualIndex)); return; } // Process this string. We should have either a value or an angle. if (str.IndexOf('-') >= 0 || IsLastItemBC()) { // If the string contains a "c" character, it's a central // angle; process the string only as far as that. PathItemType type = PathItemType.Angle; int caIndex = str.ToUpper().IndexOf('C'); if (caIndex >= 0) { str = str.Substring(0, caIndex); type = PathItemType.CentralAngle; } else { // Check if it's a deflection (if so, strip out the "d"). int dIndex = str.ToUpper().IndexOf('D'); if (dIndex >= 0) { str = str.Substring(0, dIndex) + str.Substring(dIndex + 1); type = PathItemType.Deflection; } } // Try to parse an angular value into radians. double radval; if (RadianValue.TryParse(str, out radval)) { PathItem item = new PathItem(type, null, radval); AddItem(item); return; } // Bad angle. string msg = String.Format("Malformed angle '{0}'", str); throw new ApplicationException(msg); } else { // Get the current distance units. DistanceUnit unit = GetUnits(null, false); // Grab characters that look like a floating point number string num = GetDoubleDigits(str); double val; if (!Double.TryParse(num, out val)) { string msg = String.Format("Malformed value '{0}'", str); throw new ApplicationException(msg); } // If we didn't get right to the end, we may have distance units, // or the ")" character indicating an EC. if (num.Length < str.Length && str[num.Length] != ')') { unit = GetUnits(str.Substring(num.Length), false); if (unit == null) { string msg = String.Format("Malformed value '{0}'", str); throw new ApplicationException(msg); } } PathItem item = new PathItem(PathItemType.Value, unit, val); AddItem(item); if (str.Length > num.Length && str[num.Length] == ')') { ParseWord(str.Substring(num.Length)); } return; } }