예제 #1
0
        /// <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));
        }
예제 #2
0
 /// <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());
 }
예제 #3
0
        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;
            }
        }