001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: XStringForChars.java 468655 2006-10-28 07:12:06Z minchau $
020     */
021    package org.apache.xpath.objects;
022    
023    import org.apache.xalan.res.XSLMessages;
024    import org.apache.xml.utils.FastStringBuffer;
025    import org.apache.xpath.res.XPATHErrorResources;
026    
027    
028    /**
029     * This class will wrap a FastStringBuffer and allow for
030     */
031    public class XStringForChars extends XString
032    {
033        static final long serialVersionUID = -2235248887220850467L;
034      /** The start position in the fsb. */
035      int m_start;
036      
037      /** The length of the string. */
038      int m_length;
039      
040      protected String m_strCache = null;
041      
042      /**
043       * Construct a XNodeSet object.
044       *
045       * @param val FastStringBuffer object this will wrap, must be non-null.
046       * @param start The start position in the array.
047       * @param length The number of characters to read from the array.
048       */
049      public XStringForChars(char[] val, int start, int length)
050      {
051        super(val);
052        m_start = start;
053        m_length = length;
054        if(null == val)
055          throw new IllegalArgumentException(
056                              XSLMessages.createXPATHMessage(XPATHErrorResources.ER_FASTSTRINGBUFFER_CANNOT_BE_NULL, null)); //"The FastStringBuffer argument can not be null!!");
057      }
058    
059    
060      /**
061       * Construct a XNodeSet object.
062       *
063       * @param val String object this will wrap.
064       */
065      private XStringForChars(String val)
066      {
067        super(val);
068        throw new IllegalArgumentException(
069                          XSLMessages.createXPATHMessage(XPATHErrorResources.ER_XSTRINGFORCHARS_CANNOT_TAKE_STRING, null)); //"XStringForChars can not take a string for an argument!");
070      }
071      
072      /**
073       * Cast result object to a string.
074       *
075       * @return The string this wraps or the empty string if null
076       */
077      public FastStringBuffer fsb()
078      {
079        throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_FSB_NOT_SUPPORTED_XSTRINGFORCHARS, null)); //"fsb() not supported for XStringForChars!");
080      }
081      
082      /**
083       * Cast result object to a string.
084       *
085       * @return The string this wraps or the empty string if null
086       */
087      public void appendToFsb(org.apache.xml.utils.FastStringBuffer fsb)
088      {
089        fsb.append((char[])m_obj, m_start, m_length);
090      }
091    
092      
093      /**
094       * Tell if this object contains a java String object.
095       * 
096       * @return true if this XMLString can return a string without creating one.
097       */
098      public boolean hasString()
099      {
100        return (null != m_strCache);
101      }
102    
103      
104      /**
105       * Cast result object to a string.
106       *
107       * @return The string this wraps or the empty string if null
108       */
109      public String str()
110      {
111        if(null == m_strCache)
112          m_strCache = new String((char[])m_obj, m_start, m_length);
113        
114        return m_strCache;
115      }
116      
117    
118      /**
119       * Since this object is incomplete without the length and the offset, we 
120       * have to convert to a string when this function is called.
121       *
122       * @return The java String representation of this object.
123       */
124      public Object object()
125      {
126        return str();
127      }
128    
129      /**
130       * Directly call the
131       * characters method on the passed ContentHandler for the
132       * string-value. Multiple calls to the
133       * ContentHandler's characters methods may well occur for a single call to
134       * this method.
135       *
136       * @param ch A non-null reference to a ContentHandler.
137       *
138       * @throws org.xml.sax.SAXException
139       */
140      public void dispatchCharactersEvents(org.xml.sax.ContentHandler ch)
141          throws org.xml.sax.SAXException
142      {
143        ch.characters((char[])m_obj, m_start, m_length);
144      }
145          
146      /**
147       * Directly call the
148       * comment method on the passed LexicalHandler for the
149       * string-value.
150       *
151       * @param lh A non-null reference to a LexicalHandler.
152       *
153       * @throws org.xml.sax.SAXException
154       */
155      public void dispatchAsComment(org.xml.sax.ext.LexicalHandler lh)
156          throws org.xml.sax.SAXException
157      {
158        lh.comment((char[])m_obj, m_start, m_length);
159      }
160      
161      /**
162       * Returns the length of this string.
163       *
164       * @return  the length of the sequence of characters represented by this
165       *          object.
166       */
167      public int length()
168      {
169        return m_length;
170      }
171    
172      /**
173       * Returns the character at the specified index. An index ranges
174       * from <code>0</code> to <code>length() - 1</code>. The first character
175       * of the sequence is at index <code>0</code>, the next at index
176       * <code>1</code>, and so on, as for array indexing.
177       *
178       * @param      index   the index of the character.
179       * @return     the character at the specified index of this string.
180       *             The first character is at index <code>0</code>.
181       * @exception  IndexOutOfBoundsException  if the <code>index</code>
182       *             argument is negative or not less than the length of this
183       *             string.
184       */
185      public char charAt(int index)
186      {
187        return ((char[])m_obj)[index+m_start];
188      }
189    
190      /**
191       * Copies characters from this string into the destination character
192       * array.
193       *
194       * @param      srcBegin   index of the first character in the string
195       *                        to copy.
196       * @param      srcEnd     index after the last character in the string
197       *                        to copy.
198       * @param      dst        the destination array.
199       * @param      dstBegin   the start offset in the destination array.
200       * @exception IndexOutOfBoundsException If any of the following
201       *            is true:
202       *            <ul><li><code>srcBegin</code> is negative.
203       *            <li><code>srcBegin</code> is greater than <code>srcEnd</code>
204       *            <li><code>srcEnd</code> is greater than the length of this
205       *                string
206       *            <li><code>dstBegin</code> is negative
207       *            <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than
208       *                <code>dst.length</code></ul>
209       * @exception NullPointerException if <code>dst</code> is <code>null</code>
210       */
211      public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
212      {
213        System.arraycopy((char[])m_obj, m_start+srcBegin, dst, dstBegin, srcEnd);
214      }
215      
216    }