示例#1
0
 /// <summary>
 /// Format the specified boolean value using FORTRAN L formatting rules.
 /// The width specifies the amount of space, in characters, into which 
 /// the whole number must fit or otherwise the return value is a
 /// string consisting of '*'s. If the width is zero, the string is returned
 /// without any size constraint.
 /// </summary>
 /// <param name="value">A boolean value</param>
 /// <param name="record">A FormatRecord containing formatting settings</param>
 /// <returns>A string representation of the boolean value.</returns>
 public static string FormatBoolean(bool value, FormatRecord record)
 {
     if (record == null) {
         throw new ArgumentNullException("record");
     }
     string newString = value ? "T" : "F";
     return FormatToWidth(record.FieldWidth, newString);
 }
示例#2
0
 /// <summary>
 /// Construct a FormatRecord from another instance.
 /// </summary>
 /// <param name="record">The FormatRecord to copy</param>
 public FormatRecord(FormatRecord record)
 {
     if (record == null) {
         throw new ArgumentNullException("record");
     }
     FieldWidth = record.FieldWidth;
     FormatChar = record.FormatChar;
     Count = record.Count;
     Precision = record.Precision;
     ExponentWidth = record.ExponentWidth;
     PlusRequired = record.PlusRequired;
     RawString = record.RawString;
     BlanksAsZero = record.BlanksAsZero;
     Relative = record.Relative;
 }
示例#3
0
        /// <summary>
        /// Format the specified complex number using FORTRAN F formatting rules
        /// using a double precision number. The width specifies the amount of space, in
        /// characters, into which the whole number must fit or otherwise the return value
        /// is a string consisting of '*'s. If the width is zero, the string is returned
        /// without any size constraint.
        /// 
        /// The precisionWidth is the number of units for the non-fractional part. The
        /// resulting number is truncated (and the exponent adjusted if appropriate) to fit
        /// into the given width. If the precisionWidth is zero, no truncation occurs and
        /// the number of digits in the non-fractional part is determined by the number.
        /// </summary>
        /// <param name="value">A complex number</param>
        /// <param name="recordReal">A FormatRecord containing formatting settings for the Real part</param>
        /// <param name="recordImg">A FormatRecord containing formatting settings for the Imaginary part</param>
        /// <returns>A string representation of the complex number.</returns>
        public static string FormatComplex(Complex value, FormatRecord recordReal, FormatRecord recordImg)
        {
            if (recordReal == null) {
                throw new ArgumentNullException("recordReal");
            }
            if (recordImg == null) {
                throw new ArgumentNullException("recordImg");
            }

            FormatRecord tempRecordReal = new FormatRecord(recordReal);
            FormatRecord tempRecordImg = new FormatRecord(recordImg);
            tempRecordReal.FieldWidth = 0;
            tempRecordImg.FieldWidth = 0;

            string realPart;
            string imgPart;

            switch (recordReal.FormatChar) {
                case 'D':   realPart = FormatDouble(value.Real, tempRecordReal); break;
                case 'F':   realPart = FormatFloat((float)value.Real, tempRecordReal); break;
                case 'E':   realPart = FormatExponential(value.Real, 'E', tempRecordReal); break;
                case 'G':   realPart = FormatExponential(value.Real, 'E', tempRecordReal); break;

                default:
                    throw new JComRuntimeException(string.Format("Invalid format specifier {0} for COMPLEX", recordReal.FormatChar));
            }

            switch (recordImg.FormatChar) {
                case 'D':   imgPart = FormatDouble(value.Imaginary, tempRecordImg); break;
                case 'F':   imgPart = FormatFloat((float)value.Imaginary, tempRecordImg); break;
                case 'E':   imgPart = FormatExponential(value.Imaginary, 'E', tempRecordImg); break;
                case 'G':   imgPart = FormatExponential(value.Imaginary, 'E', tempRecordImg); break;

                default:
                    throw new JComRuntimeException(string.Format("Invalid format specifier {0} for COMPLEX", recordImg.FormatChar));
            }

            if (recordReal.FieldWidth > 0 || recordImg.FieldWidth > 0) {
                return FormatToWidth(recordReal.FieldWidth + recordImg.FieldWidth + 2, string.Format("{0}  {1}", realPart, imgPart));
            }

            return string.Format("({0},{1})", realPart, imgPart);
        }
示例#4
0
 // Process any positional directions in the given record.
 void ProcessPosition(FormatRecord record)
 {
     int currentWidth = _writeIndex;
     if (record.Relative) {
         currentWidth += record.Count;
     } else {
         currentWidth = record.Count - 1;
     }
     if (currentWidth > _writeMaxIndex) {
         _writeIndex = _writeMaxIndex;
         WriteChar(' ', currentWidth - _writeMaxIndex);
     } else {
         _writeIndex = currentWidth;
     }
 }
示例#5
0
        // Format a string as specified by an "A" record.
        string FormatString(string value, FormatRecord record)
        {
            string svalue = value;

            if (record.FieldWidth > 0) {
                if (value.Length > record.FieldWidth) {
                    svalue = value.Substring(0, record.FieldWidth);
                } else {
                    svalue = value.PadLeft(record.FieldWidth);
                }
            }
            return svalue;
        }
示例#6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="JComLib.FormatParser"/> class
        /// using the specified FormatRecord to control the number parsing.
        /// </summary>
        /// <param name="buffer">The string to parse</param>
        /// <param name="record">The FormatRecord to use</param>
        public FormatParser(string buffer, FormatRecord record)
        {
            _buffer = buffer;
            _blankAsZero = (record != null) && record.BlanksAsZero;

            // Skip initial whitespace in the buffer
            while (_index < _buffer.Length && Char.IsWhiteSpace(_buffer[_index])) {
                ++_index;
            }
        }
示例#7
0
        // Do post-floating point number formatting
        static string FormatFloatToWidth(FormatRecord record, string newString)
        {
            if (record.PlusRequired == FormatOptionalPlus.Always) {
                newString = "+" + newString;
            }
            if (record.FieldWidth > 0) {
                int length = newString.Length;

                if (newString.StartsWith("0.") && length == record.FieldWidth + 1) {
                    newString = newString.Substring(1);
                }
                if (newString.StartsWith("-0.") && length == record.FieldWidth + 1) {
                    newString = "-." + newString.Substring(3);
                }
            }
            return FormatToWidth(record.FieldWidth, newString);
        }
示例#8
0
        /// <summary>
        /// Returns the next FormatRecord from the string or null if
        /// there are no further records to retrieve.
        /// </summary>
        /// <returns>A FormatRecord, or null if we reached the end</returns>
        public FormatRecord Next()
        {
            // Repeat the last record if we've still some
            // more to go.
            if (_cRepeat > 1) {
                --_cRepeat;
                return _lastRecord;
            }

            // Otherwise find the next record and return that.
            StringBuilder str = new StringBuilder();
            bool inQuote = false;

            while (_charIndex < _fmtLength) {
                char ch = NextChar();
                if (ch == '"' || ch == '\'') {
                    inQuote = !inQuote;
                    ++_charIndex;
                } else if (inQuote) {
                    str.Append(ch);
                    ++_charIndex;
                } else {
                    if (ch == ',' || Char.IsWhiteSpace(ch)) {
                        ++_charIndex;
                        continue;
                    }

                    // If we've gathered some raw string up to here
                    // then return that now.
                    if (str.Length > 0) {
                        _lastRecord = new FormatRecord();
                        _lastRecord.RawString = str.ToString();
                        return _lastRecord;
                    }

                    // Remember this offset for _lastFormatGroup later
                    int markedIndex = _charIndex-1;

                    // Check and validate any repeat specifier. Note that X, P and H are required to have
                    // a value preceding them. It's just not treated as repeat.
                    bool hasPrefixValue = Char.IsDigit(ch) || ch == '-' || ch == '+';
                    int prefixValue = ExtractNumber(1);

                    do {
                        ch = NextChar();
                        ++_charIndex;
                    } while (Char.IsWhiteSpace(ch));

                    char formatChar = ch;

                    // Valid format character?
                    if ("IFEGLA:/()TXPSHDB".IndexOf(formatChar) < 0) {
                        throw new JComRuntimeException(string.Format("Unknown format specifier character '{0}'", formatChar));
                    }

                    // End record?
                    if (formatChar == ':') {
                        return null;
                    }

                    // Record separator?
                    if (formatChar == '/') {
                        _scaleFactor = 0;
                        _lastRecord = new FormatRecord();
                        _lastRecord.IsEndRecord = true;
                        return _lastRecord;
                    }

                    // Group start
                    if (formatChar == '(') {
                        if (prefixValue < 0) {
                            throw new JComRuntimeException("Repeat count cannot be less than 0");
                        }
                        FormatGroup formatGroup = new FormatGroup();
                        formatGroup.GroupRepeat = prefixValue;
                        formatGroup.GroupStartIndex = _charIndex;
                        _groups.Push(formatGroup);

                        // Also remember this format group start in the
                        // case of a rescan.
                        if (_groups.Count == 1) {
                            _lastFormatGroup = markedIndex;
                        }
                        continue;
                    }

                    // Group end
                    if (formatChar == ')') {
                        FormatGroup formatGroup = (FormatGroup)_groups.Pop();
                        if (formatGroup == null) {
                            throw new JComRuntimeException("Parenthesis mismatch in FORMAT statement");
                        }
                        if (--formatGroup.GroupRepeat > 0) {
                            _charIndex = formatGroup.GroupStartIndex;
                            _groups.Push(formatGroup);
                        }
                        continue;
                    }

                    // Make sure a prefix value is specified for those format characters
                    // that require one, and not specified for those that don't.
                    if (formatChar == 'X' || formatChar == 'P'|| formatChar == 'H') {
                        if (!hasPrefixValue) {
                            throw new JComRuntimeException(String.Format("'{0}' specifier requires a value", formatChar));
                        }
                    } else {
                        if (hasPrefixValue && "IFEDGLA".IndexOf(formatChar) < 0) {
                            throw new JComRuntimeException(String.Format("Repeat count not permitted with '{0}' specifier", formatChar));
                        }
                        if (prefixValue < 0) {
                            throw new JComRuntimeException("Repeat count cannot be less than 0");
                        }
                        _cRepeat = prefixValue;
                    }

                    // Handle cursor positioning. The following formats are recognised:
                    //  T<n> - set the cursor position to offset <n> in the current record.
                    //  TL<n> - move the cursor back <n> characters
                    //  TR<n> - move the cursor forward <n> characters
                    if (formatChar == 'T') {
                        _lastRecord = new FormatRecord();
                        _lastRecord.FormatChar = 'T';
                        switch (NextChar()) {
                            case 'L':
                                ++_charIndex;
                                _lastRecord.Relative = true;
                                _lastRecord.Count = -ExtractNumber(0);
                                return _lastRecord;

                            case 'R':
                                ++_charIndex;
                                _lastRecord.Relative = true;
                                _lastRecord.Count = ExtractNumber(0);
                                return _lastRecord;

                            default:
                                _lastRecord.Count = ExtractNumber(0);
                                return _lastRecord;
                        }
                    }

                    // Handle forward cursor movement. This is pretty much the
                    // same as TR<n>.
                    if (formatChar == 'X') {
                        _lastRecord = new FormatRecord();
                        _lastRecord.FormatChar = 'T';
                        _lastRecord.Relative = true;
                        _lastRecord.Count = prefixValue;
                        _cRepeat = 1;
                        return _lastRecord;
                    }

                    // Handle scale factor. This influences subsequent
                    // formats on the same record.
                    if (formatChar == 'P') {
                        _scaleFactor = prefixValue;
                        _cRepeat = 1;
                        continue;
                    }

                    // Handle blank specifier which controls whether blank
                    // characters are ignored or treated as '0'.
                    if (formatChar == 'B') {
                        _blanksAsZero = NextChar() == 'Z';
                        ++_charIndex;
                        continue;
                    }

                    // Handle positive sign specification.
                    if (formatChar == 'S') {
                        switch (NextChar()) {
                            case 'P':
                                ++_charIndex;
                                _plusRequired = FormatOptionalPlus.Always;
                                break;

                            case 'S':
                                ++_charIndex;
                                _plusRequired = FormatOptionalPlus.Never;
                                break;

                            default:
                                _plusRequired = FormatOptionalPlus.Default;
                                break;
                        }
                        continue;
                    }

                    // Hollerith character output
                    // The prefix value is the count of subsequent characters in the format
                    // string that are copied literally to the output.
                    if (formatChar == 'H') {
                        while (prefixValue > 0 && _charIndex < _fmtLength) {
                            str.Append(NextChar());
                            --prefixValue;
                            ++_charIndex;
                        }
                        continue;
                    }

                    // If we get here then we're left with formatting characters that accept a
                    // width and precision specifier. So parse those off.
                    int precision = 1;
                    int exponentWidth = 0;

                    int fieldWidth = ExtractNumber(0);
                    if (NextChar() == '.') {
                        ++_charIndex;
                        precision = ExtractNumber(0);
                        if ((formatChar == 'E' || formatChar == 'G') && NextChar() == 'E') {
                            ++_charIndex;
                            exponentWidth = ExtractNumber(2);
                        }
                    }

                    // We've got a full format specifier so return
                    // that back to the caller.
                    _lastRecord = new FormatRecord();
                    _lastRecord.FormatChar = formatChar;
                    _lastRecord.FieldWidth = fieldWidth;
                    _lastRecord.Precision = precision;
                    _lastRecord.Count = _cRepeat;
                    _lastRecord.ExponentWidth = exponentWidth;
                    _lastRecord.PlusRequired = _plusRequired;
                    _lastRecord.ScaleFactor = _scaleFactor;
                    _lastRecord.BlanksAsZero = _blanksAsZero;
                    return _lastRecord;
                }
            }
            if (str.Length > 0) {
                _lastRecord = new FormatRecord();
                _lastRecord.RawString = str.ToString();
                return _lastRecord;
            }
            if (_groups.Count > 0) {
                throw new JComRuntimeException("Unclosed format specifier group");
            }
            return null;
        }
示例#9
0
 /// <summary>
 /// Parses a float from the given string. Leading blanks are ignored.
 /// Either '+' or '-' are accepted as sign characters and must appear after
 /// any leading blanks at the beginning of the string. The rest of the string
 /// must contain a fractional number of the format:
 /// 
 /// [s][nnn].[fff][Emm]
 /// 
 /// where [s] is the optional sign, [nnn] is the optional mantissa and [fff]
 /// is an optional fraction. If an exponent is specified, it must contain an
 /// exponentiation value.
 /// 
 /// If no exponent is explicitly specified then any scale factor is applied to
 /// the number.
 /// 
 /// Blanks are treated as either '0' or ignored depending on the BlanksAsZero
 /// flag in the record.
 /// </summary>
 /// <param name="floatString">A string containing a floating point number</param>
 /// <param name="record">A FormatRecord containing formatting settings</param>
 /// <returns>The floating point value of the string</returns>
 public static float ParseFloat(string floatString, FormatRecord record)
 {
     if (floatString == null) {
         throw new ArgumentNullException("floatString");
     }
     return (float)ParseDouble(floatString, record);
 }
示例#10
0
        /// <summary>
        /// Parses a double from the given string. Leading blanks are ignored.
        /// Either '+' or '-' are accepted as sign characters and must appear after
        /// any leading blanks at the beginning of the string. The rest of the string
        /// must contain a fractional number of the format:
        /// 
        /// [s][nnn].[fff][Dmm]
        /// 
        /// where [s] is the optional sign, [nnn] is the optional mantissa and [fff]
        /// is an optional fraction. If an exponent is specified, it must contain an
        /// exponentiation value.
        /// 
        /// If no exponent is explicitly specified then any scale factor is applied to
        /// the number.
        /// 
        /// Blanks are treated as either '0' or ignored depending on the BlanksAsZero
        /// flag in the record.
        /// </summary>
        /// <param name="doubleString">A string containing a double precision number</param>
        /// <param name="record">A FormatRecord containing formatting settings</param>
        /// <returns>The double precision value of the string</returns>
        public static double ParseDouble(string doubleString, FormatRecord record)
        {
            if (doubleString == null) {
                throw new ArgumentNullException("doubleString");
            }

            bool inFraction = false;
            bool hasExponentPart = false;
            int exponent = 0;
            long mantissaPart = 0;
            int sign = 1;

            FormatParser parser = new FormatParser(doubleString, record);
            char ch = parser.Next();

            if (ch == '+') {
                ch = parser.Next();
            } else if (ch == '-') {
                sign = -1;
                ch = parser.Next();
            }
            while (ch != '\0') {
                if (ch == '.') {
                    if (inFraction) {
                        throw new JComRuntimeException("Fraction already specified");
                    }
                    inFraction = true;
                } else {
                    if (!Char.IsDigit(ch)) {
                        break;
                    }
                    mantissaPart = (mantissaPart * 10) + (ch - '0');
                    if (inFraction) {
                        --exponent;
                    }
                }
                ch = parser.Next();
            }
            if ("EeDd".IndexOf(ch) >= 0) {
                ch = parser.Next();
                hasExponentPart = true;
            }
            if (hasExponentPart || ch == '+' || ch == '-') {
                int exponentSign = 1;
                int exponentPart = 0;

                if (ch == '+') {
                    ch = parser.Next();
                } else if (ch == '-') {
                    exponentSign = -1;
                    ch = parser.Next();
                }
                if (ch == '\0') {
                    throw new JComRuntimeException("Exponent must have a value");
                }
                while (ch != '\0') {
                    if (!Char.IsDigit(ch)) {
                        throw new JComRuntimeException(string.Format("Illegal character {0} in number", ch));
                    }
                    exponentPart = (exponentPart * 10) + (ch - '0');
                    ch = parser.Next();
                }
                exponent += (exponentSign * exponentPart);
                hasExponentPart = true;
            } else {
                if (ch != '\0') {
                    throw new JComRuntimeException(string.Format("Illegal character {0} in number", ch));
                }
            }
            if (!hasExponentPart && record != null) {
                exponent -= record.ScaleFactor;
            }
            bool expSign = false;
            if (exponent < 0) {
                expSign = true;
                exponent = -exponent;
            }
            if (exponent > 511) {
                exponent = 511;
            }
            double doubleExponent = 1.0;
            for (int d = 0; exponent != 0; exponent >>= 1, ++d) {
                if ((exponent & 1) != 0) {
                    doubleExponent *= powersOf10[d];
                }
            }
            double fraction = mantissaPart;
            if (expSign) {
                fraction /= doubleExponent;
            } else {
                fraction *= doubleExponent;
            }
            return fraction * sign;
        }
示例#11
0
        /// <summary>
        /// Format the specified integer number using FORTRAN I formatting rules using
        /// an integer number. The width specifies the amount of space, in characters,
        /// into which the whole number must fit or otherwise the return value is a
        /// string consisting of '*'s. If the width is zero, the string is returned
        /// without any size constraint.
        /// 
        /// The precision is the minimum number of leading zeroes that the number must
        /// contain. If this is zero, the number is not zero padded.
        /// </summary>
        /// <param name="value">An integer number</param>
        /// <param name="record">A FormatRecord containing formatting settings</param>
        /// <returns>A string representation of the integer number.</returns>
        public static string FormatInteger(int value, FormatRecord record)
        {
            if (record == null) {
                throw new ArgumentNullException("record");
            }

            StringBuilder str = new StringBuilder();
            int tempValue = Math.Abs(value);
            int fieldWidth = 0;

            do {
                char ch = (char)((tempValue % 10) + 48);
                str.Append(ch);
                tempValue /= 10;
                ++fieldWidth;
            } while (tempValue > 0);
            while (fieldWidth < record.Precision) {
                str.Append('0');
                ++fieldWidth;
            }
            if (value < 0) {
                str.Append('-');
            } else {
                if (record.PlusRequired == FormatOptionalPlus.Always) {
                    str.Append('+');
                }
            }
            return FormatToWidth(record.FieldWidth, ReverseString(str.ToString()));
        }
示例#12
0
        /// <summary>
        /// Format the specified floating point number using FORTRAN F formatting rules
        /// using a floating point number. The width specifies the amount of space, in
        /// characters, into which the whole number must fit or otherwise the return value
        /// is a string consisting of '*'s. If the width is zero, the string is returned
        /// without any size constraint.
        /// 
        /// The precision is the number of units for the non-fractional part. The
        /// resulting number is truncated (and the exponent adjusted if appropriate) to fit
        /// into the given width. If the precision is zero, no truncation occurs and
        /// the number of digits in the non-fractional part is determined by the number.
        /// </summary>
        /// <param name="value">A floating point number</param>
        /// <param name="record">A FormatRecord containing formatting settings</param>
        /// <returns>A string representation of the floating point number.</returns>
        public static string FormatFloat(float value, FormatRecord record)
        {
            if (record == null) {
                throw new ArgumentNullException("record");
            }

            // Do exponential formatting if so requested
            if (record.FormatChar == 'E') {
                return FormatExponential(value, 'E', record);
            }

            // BUGBUG: Doesn't apply the FormatOptionalPlus flag.
            // BUGBUG: Doesn't apply the scaling factor

            string formatString;
            if (record.FieldWidth == 0 && record.Precision == 0) {
                formatString = "{0:G}";
            } else {
                formatString = "{0," + record.FieldWidth.ToString() + ":F" + record.Precision.ToString() + "}";
            }
            return FormatFloatToWidth(record, string.Format(formatString, value));
        }
示例#13
0
        /// <summary>
        /// Format the specified double using FORTRAN E and D formatting rules:
        ///
        /// [+] [0] . x1x2...xd exp where:
        /// • + signifies a plus or a minus (13.5.9)
        /// • x1,x2...xd are the d most significant digits of the value of the datum after rounding
        /// • exp is a decimal exponent.
        /// </summary>
        /// <param name="value">A double precision number number</param>
        /// <param name="exponentChar">The character to be used to indicate the exponent</param>
        /// <param name="record">A FormatRecord containing formatting settings</param>
        /// <returns>A string representation of the value formatted as an exponential number.</returns>
        public static string FormatExponential(double value, char exponentChar, FormatRecord record)
        {
            if (record == null) {
                throw new ArgumentNullException("record");
            }

            int precision = record.Precision;
            int leadingZeroes = 1;

            // Extract the exponent
            int exponent = GetExponent(value);
            double newValue = value * Math.Pow(10.0, -exponent);

            // BUGBUG: Doesn't apply the FormatOptionalPlus flag.

            while (newValue >= 1.0 || newValue < -1.0) {
                ++exponent;
                newValue = value * Math.Pow(10.0, -exponent);
            }

            if (record.ScaleFactor != 0) {
                newValue *= Math.Pow(10.0, record.ScaleFactor);
                exponent -= record.ScaleFactor;

                // Decimal normalization with scale factor
                if (record.ScaleFactor <= 0 && record.ScaleFactor > -record.ExponentWidth) {
                    leadingZeroes = Math.Abs(record.ScaleFactor);
                    precision = record.ExponentWidth - Math.Abs(record.ScaleFactor);
                } else if (record.ScaleFactor > 0 && record.ScaleFactor < record.ExponentWidth + 2) {
                    precision = (precision - record.ScaleFactor) + 1;
                }
            }

            string mantissaFormat = new string('0', leadingZeroes);
            string fractionalFormat = new string('0', precision);
            string exponentPortion;

            if (record.ExponentWidth > 0) {
                string exponentFormat = new string('0', record.ExponentWidth);
                exponentPortion = exponentChar.ToString() + exponent.ToString("+" + exponentFormat + ";-" + exponentFormat);
            } else if (exponent <= 99) {
                exponentPortion = exponentChar.ToString() + exponent.ToString("+00;-00");
            } else if (exponent < 999) {
                exponentPortion = exponent.ToString("+000;-000");
            } else {
                // TODO: Run-time failure here. Exponent too big for E/D format
                return string.Empty;
            }
            return FormatFloatToWidth(record, newValue.ToString(mantissaFormat + "." + fractionalFormat) + exponentPortion);
        }
示例#14
0
        /// <summary>
        /// Format the specified double precision number using FORTRAN F formatting rules
        /// using a double precision number. The width specifies the amount of space, in
        /// characters, into which the whole number must fit or otherwise the return value
        /// is a string consisting of '*'s. If the width is zero, the string is returned
        /// without any size constraint.
        /// 
        /// The precisionWidth is the number of units for the non-fractional part. The
        /// resulting number is truncated (and the exponent adjusted if appropriate) to fit
        /// into the given width. If the precisionWidth is zero, no truncation occurs and
        /// the number of digits in the non-fractional part is determined by the number.
        /// </summary>
        /// <param name="value">A floating point number</param>
        /// <param name="record">A FormatRecord containing formatting settings</param>
        /// <returns>A string representation of the floating point number.</returns>
        public static string FormatDouble(double value, FormatRecord record)
        {
            if (record == null) {
                throw new ArgumentNullException("record");
            }

            // Do exponential formatting if so requested
            if (record.FormatChar == 'E') {
                return FormatExponential(value, 'E', record);
            }
            if (record.FormatChar == 'G') {
                if (value < 0.1 || value > Math.Pow(10, record.Precision)) {
                    return FormatExponential(value, 'E', record);
                }
            }

            // BUGBUG: Doesn't apply the FormatOptionalPlus flag.
            // BUGBUG: Doesn't apply the scaling factor
            // BUGBUG: Exponent character should be 'D' for double.

            string formatString;
            if (record.FieldWidth == 0 && record.Precision == 0) {
                formatString = "{0:G}";
            } else {
                formatString = "{0," + record.FieldWidth.ToString() + ":F" + record.Precision.ToString() + "}";
            }
            return FormatFloatToWidth(record, string.Format(formatString, value));
        }
示例#15
0
 // Make sure the value is valid for the given format record type. Throw
 // a run-time exception if there's a mismatch.
 void VerifyFormatMatch(FormatRecord record, object value)
 {
     char ch = record.FormatChar;
     bool match = true;
     switch (ch) {
         case 'A':   match = (value is String || value is FixedString); break;
         case 'I':   match = (value is Int32); break;
         case 'L':   match = (value is Boolean); break;
         case 'F':   match = (value is float || value is double || value is Complex); break;
         case 'G':   match = (value is float || value is double || value is Complex); break;
         case 'E':   match = (value is float || value is double || value is Complex); break;
     }
     if (!match) {
         string realName = value.GetType().Name;
         switch (realName.ToLower()) {
             case "int32":       realName = "INTEGER"; break;
             case "single":      realName = "REAL"; break;
             case "double":      realName = "DOUBLE"; break;
             case "string":      realName = "CHARACTER"; break;
             case "fixedstring": realName = "CHARACTER"; break;
         }
         throw new JComRuntimeException(string.Format("Format record mismatch: '{0}' specifier and {1} type", ch, realName));
     }
 }
示例#16
0
        /// <summary>
        /// Parses an integer from the given string. Leading blanks are ignored.
        /// Either '+' or '-' are accepted as sign characters and must appear after
        /// any leading blanks at the beginning of the string. The rest of the string
        /// must contain digits or blanks. Blanks are treated as either '0' or ignored
        /// depending on the BlanksAsZero flag in the record.
        /// </summary>
        /// <param name="intString">A string containing an integer number</param>
        /// <param name="record">A FormatRecord specifier</param>
        /// <returns>The integer value of the string</returns>
        public static int ParseInteger(string intString, FormatRecord record)
        {
            if (intString == null) {
                throw new ArgumentNullException("intString");
            }

            int intValue = 0;
            int sign = 1;

            FormatParser parser = new FormatParser(intString, record);
            char ch = parser.Next();

            if (ch == '+') {
                ch = parser.Next();
            } else if (ch == '-') {
                sign = -1;
                ch = parser.Next();
            }
            while (ch != '\0') {
                if (!Char.IsDigit(ch)) {
                    throw new JComRuntimeException(string.Format("Illegal character {0} in number", ch));
                }
                intValue = (intValue * 10) + (ch - '0');
                ch = parser.Next();
            }
            return intValue * sign;
        }
示例#17
0
 // Process any positional directions in the given record.
 void ProcessPosition(FormatRecord record)
 {
     if (record.IsPositional && _line != null) {
         if (record.Relative) {
             _readIndex += record.Count;
         } else {
             _readIndex = record.Count;
         }
         _readIndex = Math.Max(_readIndex, 0);
         _readIndex = Math.Min(_readIndex, _line.Length - 1);
     }
 }