// XPath spec $4.2, string() public QilNode ConvertToString(QilNode n) { switch (n.XmlType.TypeCode) { case XmlTypeCode.Boolean: return( n.NodeType == QilNodeType.True ? (QilNode)String("true") : n.NodeType == QilNodeType.False ? (QilNode)String("false") : /*default: */ (QilNode)Conditional(n, String("true"), String("false")) ); case XmlTypeCode.Double: return(n.NodeType == QilNodeType.LiteralDouble ? (QilNode)String(XPathConvert.DoubleToString((double)(QilLiteral)n)) : (QilNode)XsltConvert(n, T.StringX) ); case XmlTypeCode.String: return(n); default: if (n.XmlType.IsNode) { return(XPathNodeValue(SafeDocOrderDistinct(n))); } ExpectAny(n); return(XsltConvert(n, T.StringX)); } }
private void ScanNumber() { Debug.Assert(xmlCharType.IsDigit(curChar)); int start = curIndex; while (xmlCharType.IsDigit(curChar)) { NextChar(); } if (curChar == '.') { NextChar(); while (xmlCharType.IsDigit(curChar)) { NextChar(); } } if ((curChar & (~0x20)) == 'E') { NextChar(); if (curChar == '+' || curChar == '-') { NextChar(); } while (xmlCharType.IsDigit(curChar)) { NextChar(); } throw CreateException(Res.XPath_ScientificNotation); } this.kind = LexKind.Number; this.numberValue = XPathConvert.StringToDouble(xpathExpr.Substring(start, curIndex - start)); }
public static double ToDouble(XPathItem item) { XsltLibrary.CheckXsltValue(item); if (item.IsNode) { return(XPathConvert.StringToDouble(item.Value)); } Type itemType = item.ValueType; if (itemType == StringType) { return(XPathConvert.StringToDouble(item.Value)); } else if (itemType == DoubleType) { return(item.ValueAsDouble); } else { Debug.Assert(itemType == BooleanType, $"Unexpected type of atomic sequence {itemType}"); return(item.ValueAsBoolean ? 1d : 0d); } }
public void SetVersion(string version, string attName) { double versionNum = XPathConvert.StringToDouble(version); if (double.IsNaN(versionNum)) { ReportError(/*[XT0110]*/ Res.Xslt_InvalidAttrValue, attName, version); versionNum = 1.0; } scopeManager.ForwardCompatibility = (versionNum != 1.0); }
public static string ToString(XPathItem item) { XsltLibrary.CheckXsltValue(item); // Use XPath 1.0 rules to convert double to string if (!item.IsNode && item.ValueType == DoubleType) { return(XPathConvert.DoubleToString(item.ValueAsDouble)); } return(item.Value); }
private void ScanFraction() { Debug.Assert(xmlCharType.IsDigit(curChar)); int start = curIndex - 1; Debug.Assert(0 <= start && xpathExpr[start] == '.'); while (xmlCharType.IsDigit(curChar)) { NextChar(); } this.kind = LexKind.Number; this.numberValue = XPathConvert.StringToDouble(xpathExpr.Substring(start, curIndex - start)); }
private void SetVersion(int attVersion) { MoveToLiteralAttribute(attVersion); Debug.Assert(IsKeyword(_atoms.Version)); double version = XPathConvert.StringToDouble(Value); if (double.IsNaN(version)) { ReportError(/*[XT0110]*/ SR.Xslt_InvalidAttrValue, _atoms.Version, Value); #if XSLT2 version = 2.0; #else version = 1.0; #endif } SetVersion(version); }
/* * PrimaryExpr ::= Literal | Number | VariableReference | '(' Expr ')' | FunctionCall */ private Node ParsePrimaryExpr() { Debug.Assert(IsPrimaryExpr()); Node opnd; switch (scanner.Kind) { case LexKind.String: opnd = builder.String(scanner.StringValue); scanner.NextLex(); break; case LexKind.Number: opnd = builder.Number(XPathConvert.StringToDouble(scanner.RawValue)); scanner.NextLex(); break; case LexKind.Dollar: int startChar = scanner.LexStart; scanner.NextLex(); scanner.CheckToken(LexKind.Name); PushPosInfo(startChar, scanner.LexStart + scanner.LexSize); opnd = builder.Variable(scanner.Prefix, scanner.Name); PopPosInfo(); scanner.NextLex(); break; case LexKind.LParens: scanner.NextLex(); opnd = ParseExpr(); scanner.PassToken(LexKind.RParens); break; default: Debug.Assert( scanner.Kind == LexKind.Name && scanner.CanBeFunction && !IsNodeType(scanner), "IsPrimaryExpr() returned true, but the lexeme is not recognized" ); opnd = ParseFunctionCall(); break; } return(opnd); }
private static string ConvertToDecimal(double val, int minLen, char zero, string groupSeparator, int groupSize) { Debug.Assert(val >= 0 && val == Math.Round(val), "ConvertToArabic operates on non-negative integer numbers only"); string str = XPathConvert.DoubleToString(val); int shift = zero - '0'; // Figure out new string length without separators int oldLen = str.Length; int newLen = Math.Max(oldLen, minLen); // Calculate length of string with separators if (groupSize != 0) { Debug.Assert(groupSeparator.Length == 1); checked { newLen += (newLen - 1) / groupSize; } } // If the new number of characters equals the old one, no changes need to be made if (newLen == oldLen && shift == 0) { return(str); } // If grouping is not needed, add zero padding only if (groupSize == 0 && shift == 0) { return(str.PadLeft(newLen, zero)); } // Add both grouping separators and zero padding to the string representation of a number #if true unsafe { char *result = stackalloc char[newLen]; char separator = (groupSeparator.Length > 0) ? groupSeparator[0] : ' '; fixed(char *pin = str) { char *pOldEnd = pin + oldLen - 1; char *pNewEnd = result + newLen - 1; int cnt = groupSize; while (true) { // Move digit to its new location (zero if we've run out of digits) *pNewEnd-- = (pOldEnd >= pin) ? (char)(*pOldEnd-- + shift) : zero; if (pNewEnd < result) { break; } if (/*groupSize > 0 && */ --cnt == 0) { // Every groupSize digits insert the separator *pNewEnd-- = separator; cnt = groupSize; Debug.Assert(pNewEnd >= result, "Separator cannot be the first character"); } } } return(new string(result, 0, newLen)); } #else // Safe version is about 20% slower after NGEN char[] result = new char[newLen]; char separator = (groupSeparator.Length > 0) ? groupSeparator[0] : ' '; int oldEnd = oldLen - 1; int newEnd = newLen - 1; int cnt = groupSize; while (true) { // Move digit to its new location (zero if we've run out of digits) result[newEnd--] = (oldEnd >= 0) ? (char)(str[oldEnd--] + shift) : zero; if (newEnd < 0) { break; } if (/*groupSize > 0 && */ --cnt == 0) { // Every groupSize digits insert the separator result[newEnd--] = separator; cnt = groupSize; Debug.Assert(newEnd >= 0, "Separator cannot be the first character"); } } return(new string(result, 0, newLen)); #endif }
/// <summary> /// Format the given xsl:number place marker /// </summary> /// <param name="val">Place marker - either a sequence of ints, or a double singleton</param> /// <returns>Formatted string</returns> public string FormatSequence(IList <XPathItem> val) { StringBuilder sb = new StringBuilder(); // If the value was supplied directly, in the 'value' attribute, check its validity if (val.Count == 1 && val[0].ValueType == typeof(double)) { double dblVal = val[0].ValueAsDouble; if (!(0.5 <= dblVal && dblVal < double.PositiveInfinity)) { // Errata E24: It is an error if the number is NaN, infinite or less than 0.5; an XSLT processor may signal // the error; if it does not signal the error, it must recover by converting the number to a string as if // by a call to the 'string' function and inserting the resulting string into the result tree. return(XPathConvert.DoubleToString(dblVal)); } } if (_tokens == null) { // Special case of the default format for (int idx = 0; idx < val.Count; idx++) { if (idx > 0) { sb.Append('.'); } FormatItem(sb, val[idx], DefaultStartChar, 1); } } else { int cFormats = _tokens.Count; TokenInfo prefix = _tokens[0], suffix; if (cFormats % 2 == 0) { suffix = null; } else { suffix = _tokens[--cFormats]; } TokenInfo periodicSeparator = 2 < cFormats ? _tokens[cFormats - 2] : s_defaultSeparator; TokenInfo periodicFormat = 0 < cFormats ? _tokens[cFormats - 1] : s_defaultFormat; if (prefix != null) { prefix.AssertSeparator(true); sb.Append(prefix.formatString, prefix.startIdx, prefix.length); } int valCount = val.Count; for (int i = 0; i < valCount; i++) { int formatIndex = i * 2; bool haveFormat = formatIndex < cFormats; if (i > 0) { TokenInfo thisSeparator = haveFormat ? _tokens[formatIndex + 0] : periodicSeparator; thisSeparator.AssertSeparator(true); sb.Append(thisSeparator.formatString, thisSeparator.startIdx, thisSeparator.length); } TokenInfo thisFormat = haveFormat ? _tokens[formatIndex + 1] : periodicFormat; thisFormat.AssertSeparator(false); FormatItem(sb, val[i], thisFormat.startChar, thisFormat.length); } if (suffix != null) { suffix.AssertSeparator(true); sb.Append(suffix.formatString, suffix.startIdx, suffix.length); } } return(sb.ToString()); }
//------------------------------------------------------------------------ // ToString (internal type to internal type) //------------------------------------------------------------------------ public static string ToString(double value) { return(XPathConvert.DoubleToString(value)); }
//------------------------------------------------------------------------ // ToDouble (internal type to internal type) //------------------------------------------------------------------------ public static double ToDouble(string value) { return(XPathConvert.StringToDouble(value)); }