FileDocCategorySizeDatePackage
XStringForFSB.javaAPI DocJava SE 5 API28261Fri Aug 26 14:56:10 BST 2005com.sun.org.apache.xpath.internal.objects

XStringForFSB

public class XStringForFSB extends XString
This class will wrap a FastStringBuffer and allow for

Fields Summary
int
m_start
The start position in the fsb.
int
m_length
The length of the string.
protected String
m_strCache
If the str() function is called, the string will be cached here.
protected int
m_hash
cached hash code
Constructors Summary
public XStringForFSB(FastStringBuffer val, int start, int length)
Construct a XNodeSet object.

param
val FastStringBuffer object this will wrap, must be non-null.
param
start The start position in the array.
param
length The number of characters to read from the array.


                                      
        
  

    super(val);

    m_start = start;
    m_length = length;

    if (null == val)
      throw new IllegalArgumentException(
        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_FASTSTRINGBUFFER_CANNOT_BE_NULL, null));
  
private XStringForFSB(String val)
Construct a XNodeSet object.

param
val String object this will wrap.


    super(val);

    throw new IllegalArgumentException(
      XSLMessages.createXPATHMessage(XPATHErrorResources.ER_FSB_CANNOT_TAKE_STRING, null)); // "XStringForFSB can not take a string for an argument!");
  
Methods Summary
public voidappendToFsb(com.sun.org.apache.xml.internal.utils.FastStringBuffer fsb)
Cast result object to a string.

return
The string this wraps or the empty string if null

    // %OPT% !!! FSB has to be updated to take partial fsb's for append.
    fsb.append(str());
  
public charcharAt(int index)
Returns the character at the specified index. An index ranges from 0 to length() - 1. The first character of the sequence is at index 0, the next at index 1, and so on, as for array indexing.

param
index the index of the character.
return
the character at the specified index of this string. The first character is at index 0.
exception
IndexOutOfBoundsException if the index argument is negative or not less than the length of this string.

    return fsb().charAt(m_start + index);
  
public intcompareTo(com.sun.org.apache.xml.internal.utils.XMLString xstr)
Compares two strings lexicographically.

param
anotherString the String to be compared. NEEDSDOC @param xstr
return
the value 0 if the argument string is equal to this string; a value less than 0 if this string is lexicographically less than the string argument; and a value greater than 0 if this string is lexicographically greater than the string argument.
exception
java.lang.NullPointerException if anotherString is null.


    int len1 = m_length;
    int len2 = xstr.length();
    int n = Math.min(len1, len2);
    FastStringBuffer fsb = fsb();
    int i = m_start;
    int j = 0;

    while (n-- != 0)
    {
      char c1 = fsb.charAt(i);
      char c2 = xstr.charAt(j);

      if (c1 != c2)
      {
        return c1 - c2;
      }

      i++;
      j++;
    }

    return len1 - len2;
  
public intcompareToIgnoreCase(com.sun.org.apache.xml.internal.utils.XMLString xstr)
Compares two strings lexicographically, ignoring case considerations. This method returns an integer whose sign is that of this.toUpperCase().toLowerCase().compareTo( str.toUpperCase().toLowerCase()).

Note that this method does not take locale into account, and will result in an unsatisfactory ordering for certain locales. The java.text package provides collators to allow locale-sensitive ordering.

param
str the String to be compared. NEEDSDOC @param xstr
return
a negative integer, zero, or a positive integer as the the specified String is greater than, equal to, or less than this String, ignoring case considerations.
see
java.text.Collator#compare(String, String)
since
1.2


    int len1 = m_length;
    int len2 = xstr.length();
    int n = Math.min(len1, len2);
    FastStringBuffer fsb = fsb();
    int i = m_start;
    int j = 0;

    while (n-- != 0)
    {
      char c1 = Character.toLowerCase(fsb.charAt(i));
      char c2 = Character.toLowerCase(xstr.charAt(j));

      if (c1 != c2)
      {
        return c1 - c2;
      }

      i++;
      j++;
    }

    return len1 - len2;
  
public com.sun.org.apache.xml.internal.utils.XMLStringconcat(java.lang.String str)
Concatenates the specified string to the end of this string.

param
str the String that is concatenated to the end of this String.
return
a string that represents the concatenation of this object's characters followed by the string argument's characters.
exception
java.lang.NullPointerException if str is null.


    // %OPT% Make an FSB here?
    return new XString(str().concat(str));
  
public voiddispatchAsComment(org.xml.sax.ext.LexicalHandler lh)
Directly call the comment method on the passed LexicalHandler for the string-value.

param
lh A non-null reference to a LexicalHandler.
throws
org.xml.sax.SAXException

    fsb().sendSAXComment(lh, m_start, m_length);
  
public voiddispatchCharactersEvents(org.xml.sax.ContentHandler ch)
Directly call the characters method on the passed ContentHandler for the string-value. Multiple calls to the ContentHandler's characters methods may well occur for a single call to this method.

param
ch A non-null reference to a ContentHandler.
throws
org.xml.sax.SAXException

    fsb().sendSAXcharacters(ch, m_start, m_length);
  
public booleanequals(com.sun.org.apache.xml.internal.utils.XMLString obj2)
Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.

param
anObject the object to compare this String against. NEEDSDOC @param obj2
return
true if the String are equal; false otherwise.
see
java.lang.String#compareTo(java.lang.String)
see
java.lang.String#equalsIgnoreCase(java.lang.String)


    if (this == obj2)
    {
      return true;
    }

    int n = m_length;

    if (n == obj2.length())
    {
      FastStringBuffer fsb = fsb();
      int i = m_start;
      int j = 0;

      while (n-- != 0)
      {
        if (fsb.charAt(i) != obj2.charAt(j))
        {
          return false;
        }

        i++;
        j++;
      }

      return true;
    }

    return false;
  
public booleanequals(com.sun.org.apache.xpath.internal.objects.XObject obj2)
Tell if two objects are functionally equal.

param
obj2 Object to compare this to
return
true if the two objects are equal
throws
javax.xml.transform.TransformerException


    if (this == obj2)
    {
      return true;
    }
    if(obj2.getType() == XObject.CLASS_NUMBER)
    	return obj2.equals(this);

    String str = obj2.str();
    int n = m_length;

    if (n == str.length())
    {
      FastStringBuffer fsb = fsb();
      int i = m_start;
      int j = 0;

      while (n-- != 0)
      {
        if (fsb.charAt(i) != str.charAt(j))
        {
          return false;
        }

        i++;
        j++;
      }

      return true;
    }

    return false;
  
public booleanequals(java.lang.String anotherString)
Tell if two objects are functionally equal.

param
obj2 Object to compare this to NEEDSDOC @param anotherString
return
true if the two objects are equal
throws
javax.xml.transform.TransformerException


    int n = m_length;

    if (n == anotherString.length())
    {
      FastStringBuffer fsb = fsb();
      int i = m_start;
      int j = 0;

      while (n-- != 0)
      {
        if (fsb.charAt(i) != anotherString.charAt(j))
        {
          return false;
        }

        i++;
        j++;
      }

      return true;
    }

    return false;
  
public booleanequals(java.lang.Object obj2)
Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.

param
anObject the object to compare this String against. NEEDSDOC @param obj2
return
true if the String are equal; false otherwise.
see
java.lang.String#compareTo(java.lang.String)
see
java.lang.String#equalsIgnoreCase(java.lang.String)


    if (null == obj2)
      return false;
      
    if(obj2 instanceof XNumber)
    	return obj2.equals(this);

      // In order to handle the 'all' semantics of 
      // nodeset comparisons, we always call the 
      // nodeset function.
    else if (obj2 instanceof XNodeSet)
      return obj2.equals(this);
    else if (obj2 instanceof XStringForFSB)
      return equals((XMLString) this);
    else
      return equals(obj2.toString());
  
public booleanequalsIgnoreCase(java.lang.String anotherString)
Compares this String to another String, ignoring case considerations. Two strings are considered equal ignoring case if they are of the same length, and corresponding characters in the two strings are equal ignoring case.

param
anotherString the String to compare this String against.
return
true if the argument is not null and the Strings are equal, ignoring case; false otherwise.
see
#equals(Object)
see
java.lang.Character#toLowerCase(char)
see
java.lang.Character#toUpperCase(char)

    return (m_length == anotherString.length())
           ? str().equalsIgnoreCase(anotherString) : false;
  
public com.sun.org.apache.xml.internal.utils.XMLStringfixWhiteSpace(boolean trimHead, boolean trimTail, boolean doublePunctuationSpaces)
Conditionally trim all leading and trailing whitespace in the specified String. All strings of white space are replaced by a single space character (#x20), except spaces after punctuation which receive double spaces if doublePunctuationSpaces is true. This function may be useful to a formatter, but to get first class results, the formatter should probably do it's own white space handling based on the semantics of the formatting object.

param
trimHead Trim leading whitespace?
param
trimTail Trim trailing whitespace?
param
doublePunctuationSpaces Use double spaces for punctuation?
return
The trimmed string.


    int end = m_length + m_start;
    char[] buf = new char[m_length];
    FastStringBuffer fsb = fsb();
    boolean edit = false;

    /* replace S to ' '. and ' '+ -> single ' '. */
    int d = 0;
    boolean pres = false;

    for (int s = m_start; s < end; s++)
    {
      char c = fsb.charAt(s);

      if (isSpace(c))
      {
        if (!pres)
        {
          if (' " != c)
          {
            edit = true;
          }

          buf[d++] = ' ";

          if (doublePunctuationSpaces && (d != 0))
          {
            char prevChar = buf[d - 1];

            if (!((prevChar == '.") || (prevChar == '!")
                  || (prevChar == '?")))
            {
              pres = true;
            }
          }
          else
          {
            pres = true;
          }
        }
        else
        {
          edit = true;
          pres = true;
        }
      }
      else
      {
        buf[d++] = c;
        pres = false;
      }
    }

    if (trimTail && 1 <= d && ' " == buf[d - 1])
    {
      edit = true;

      d--;
    }

    int start = 0;

    if (trimHead && 0 < d && ' " == buf[0])
    {
      edit = true;

      start++;
    }

    XMLStringFactory xsf = XMLStringFactoryImpl.getFactory();

    return edit ? xsf.newstr(buf, start, d - start) : this;
  
public com.sun.org.apache.xml.internal.utils.FastStringBufferfsb()
Cast result object to a string.

return
The string this wraps or the empty string if null

    return ((FastStringBuffer) m_obj);
  
public voidgetChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
Copies characters from this string into the destination character array.

param
srcBegin index of the first character in the string to copy.
param
srcEnd index after the last character in the string to copy.
param
dst the destination array.
param
dstBegin the start offset in the destination array.
exception
IndexOutOfBoundsException If any of the following is true:
  • srcBegin is negative.
  • srcBegin is greater than srcEnd
  • srcEnd is greater than the length of this string
  • dstBegin is negative
  • dstBegin+(srcEnd-srcBegin) is larger than dst.length
exception
NullPointerException if dst is null


    // %OPT% Need to call this on FSB when it is implemented.
    // %UNTESTED% (I don't think anyone calls this yet?)
    int n = srcEnd - srcBegin;

    if (n > m_length)
      n = m_length;

    if (n > (dst.length - dstBegin))
      n = (dst.length - dstBegin);

    int end = srcBegin + m_start + n;
    int d = dstBegin;
    FastStringBuffer fsb = fsb();

    for (int i = srcBegin + m_start; i < end; i++)
    {
      dst[d++] = fsb.charAt(i);
    }
  
public booleanhasString()
Tell if this object contains a java String object.

return
true if this XMLString can return a string without creating one.

    return (null != m_strCache);
  
public inthashCode()
Returns a hashcode for this string. The hashcode for a String object is computed as
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
using int arithmetic, where s[i] is the ith character of the string, n is the length of the string, and ^ indicates exponentiation. (The hash value of the empty string is zero.)

return
a hash code value for this object.

    // Commenting this out because in JDK1.1.8 and VJ++
    // we don't match XMLStrings. Defaulting to the super
    // causes us to create a string, but at this point
    // this only seems to get called in key processing.
    // Maybe we can live with it?
    
/*
    int h = m_hash;

    if (h == 0)
    {
      int off = m_start;
      int len = m_length;
      FastStringBuffer fsb = fsb();

      for (int i = 0; i < len; i++)
      {
        h = 31 * h + fsb.charAt(off);

        off++;
      }

      m_hash = h;
    }
    */

    return super.hashCode(); // h;
  
public intindexOf(int ch)
Returns the index within this string of the first occurrence of the specified character. If a character with value ch occurs in the character sequence represented by this String object, then the index of the first such occurrence is returned -- that is, the smallest value k such that:
this.charAt(k) == ch
is true. If no such character occurs in this string, then -1 is returned.

param
ch a character.
return
the index of the first occurrence of the character in the character sequence represented by this object, or -1 if the character does not occur.

    return indexOf(ch, 0);
  
public intindexOf(int ch, int fromIndex)
Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.

If a character with value ch occurs in the character sequence represented by this String object at an index no smaller than fromIndex, then the index of the first such occurrence is returned--that is, the smallest value k such that:

(this.charAt(k) == ch) && (k >= fromIndex)
is true. If no such character occurs in this string at or after position fromIndex, then -1 is returned.

There is no restriction on the value of fromIndex. If it is negative, it has the same effect as if it were zero: this entire string may be searched. If it is greater than the length of this string, it has the same effect as if it were equal to the length of this string: -1 is returned.

param
ch a character.
param
fromIndex the index to start the search from.
return
the index of the first occurrence of the character in the character sequence represented by this object that is greater than or equal to fromIndex, or -1 if the character does not occur.


    int max = m_start + m_length;
    FastStringBuffer fsb = fsb();

    if (fromIndex < 0)
    {
      fromIndex = 0;
    }
    else if (fromIndex >= m_length)
    {

      // Note: fromIndex might be near -1>>>1.
      return -1;
    }

    for (int i = m_start + fromIndex; i < max; i++)
    {
      if (fsb.charAt(i) == ch)
      {
        return i - m_start;
      }
    }

    return -1;
  
private static booleanisSpace(char ch)
Returns whether the specified ch conforms to the XML 1.0 definition of whitespace. Refer to the definition of S for details.

param
ch Character to check as XML whitespace.
return
=true if ch is XML whitespace; otherwise =false.

    return XMLCharacterRecognizer.isWhiteSpace(ch);  // Take the easy way out for now.
  
public intlength()
Returns the length of this string.

return
the length of the sequence of characters represented by this object.

    return m_length;
  
public java.lang.Objectobject()
Since this object is incomplete without the length and the offset, we have to convert to a string when this function is called.

return
The java String representation of this object.

    return str();
  
public booleanstartsWith(com.sun.org.apache.xml.internal.utils.XMLString prefix, int toffset)
Tests if this string starts with the specified prefix beginning a specified index.

param
prefix the prefix.
param
toffset where to begin looking in the string.
return
true if the character sequence represented by the argument is a prefix of the substring of this object starting at index toffset; false otherwise. The result is false if toffset is negative or greater than the length of this String object; otherwise the result is the same as the result of the expression
this.subString(toffset).startsWith(prefix)
exception
java.lang.NullPointerException if prefix is null.


    FastStringBuffer fsb = fsb();
    int to = m_start + toffset;
    int tlim = m_start + m_length;
    int po = 0;
    int pc = prefix.length();

    // Note: toffset might be near -1>>>1.
    if ((toffset < 0) || (toffset > m_length - pc))
    {
      return false;
    }

    while (--pc >= 0)
    {
      if (fsb.charAt(to) != prefix.charAt(po))
      {
        return false;
      }

      to++;
      po++;
    }

    return true;
  
public booleanstartsWith(com.sun.org.apache.xml.internal.utils.XMLString prefix)
Tests if this string starts with the specified prefix.

param
prefix the prefix.
return
true if the character sequence represented by the argument is a prefix of the character sequence represented by this string; false otherwise. Note also that true will be returned if the argument is an empty string or is equal to this String object as determined by the {@link #equals(Object)} method.
exception
java.lang.NullPointerException if prefix is null.
since
JDK1. 0

    return startsWith(prefix, 0);
  
public java.lang.Stringstr()
Cast result object to a string.

return
The string this wraps or the empty string if null


    if (null == m_strCache)
    {
      m_strCache = fsb().getString(m_start, m_length);

//      strCount++;
//
//      RuntimeException e = new RuntimeException("Bad!  Bad!");
//      java.io.CharArrayWriter writer = new java.io.CharArrayWriter();
//      java.io.PrintWriter pw = new java.io.PrintWriter(writer);
//
//      e.printStackTrace(pw);
//
//      String str = writer.toString();
//
//      str = str.substring(0, 600);
//
//      if (null == xtable.get(str))
//      {
//        xtable.put(str, str);
//        System.out.println(str);
//      }
//      System.out.println("strCount: " + strCount);

//      throw e;
//      e.printStackTrace();
      // System.exit(-1);
    }

    return m_strCache;
  
public com.sun.org.apache.xml.internal.utils.XMLStringsubstring(int beginIndex)
Returns a new string that is a substring of this string. The substring begins with the character at the specified index and extends to the end of this string.

Examples:

"unhappy".substring(2) returns "happy"
"Harbison".substring(3) returns "bison"
"emptiness".substring(9) returns "" (an empty string)

param
beginIndex the beginning index, inclusive.
return
the specified substring.
exception
IndexOutOfBoundsException if beginIndex is negative or larger than the length of this String object.


    int len = m_length - beginIndex;

    if (len <= 0)
      return XString.EMPTYSTRING;
    else
    {
      int start = m_start + beginIndex;

      return new XStringForFSB(fsb(), start, len);
    }
  
public com.sun.org.apache.xml.internal.utils.XMLStringsubstring(int beginIndex, int endIndex)
Returns a new string that is a substring of this string. The substring begins at the specified beginIndex and extends to the character at index endIndex - 1. Thus the length of the substring is endIndex-beginIndex.

param
beginIndex the beginning index, inclusive.
param
endIndex the ending index, exclusive.
return
the specified substring.
exception
IndexOutOfBoundsException if the beginIndex is negative, or endIndex is larger than the length of this String object, or beginIndex is larger than endIndex.


    int len = endIndex - beginIndex;

    if (len > m_length)
      len = m_length;

    if (len <= 0)
      return XString.EMPTYSTRING;
    else
    {
      int start = m_start + beginIndex;

      return new XStringForFSB(fsb(), start, len);
    }
  
public doubletoDouble()
Convert a string to a double -- Allowed input is in fixed notation ddd.fff. %OPT% CHECK PERFORMANCE against generating a Java String and converting it to double. The advantage of running in native machine code -- perhaps even microcode, on some systems -- may more than make up for the cost of allocating and discarding the additional object. We need to benchmark this. %OPT% More importantly, we need to decide whether we _care_ about the performance of this operation. Does XString.toDouble constitute any measurable percentage of our typical runtime? I suspect not!

return
A double value representation of the string, or return Double.NaN if the string can not be converted.

    if(m_length == 0)
      return Double.NaN;
    int i;
    char c;
    String valueString = fsb().getString(m_start,m_length);
    
    // The following are permitted in the Double.valueOf, but not by the XPath spec:
    // - a plus sign
    // - The use of e or E to indicate exponents
    // - trailing f, F, d, or D
    // See function comments; not sure if this is slower than actually doing the
    // conversion ourselves (as was before).
    
    for (i=0;i<m_length;i++)
      if (!XMLCharacterRecognizer.isWhiteSpace(valueString.charAt(i)))
        break;
    if (valueString.charAt(i) == '-")
      i++;
    for (;i<m_length;i++) {
      c = valueString.charAt(i);
      if (c != '." && (c < '0" || c > '9"))
        break;
    }   	    	
    for (;i<m_length;i++)
      if (!XMLCharacterRecognizer.isWhiteSpace(valueString.charAt(i)))
        break;
    if (i != m_length)
      return Double.NaN;
    	
    try {
      return new Double(valueString).doubleValue();
    } catch (NumberFormatException nfe) {
      // This should catch double periods, empty strings.
      return Double.NaN;
    }
  
public com.sun.org.apache.xml.internal.utils.XMLStringtrim()
Removes white space from both ends of this string.

return
this string, with white space removed from the front and end.

    return fixWhiteSpace(true, true, false);