~ubuntu-branches/ubuntu/saucy/libxalan2-java/saucy-security

« back to all changes in this revision

Viewing changes to src/org/apache/xalan/transformer/NumeratorFormatter.java

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2008-04-27 10:20:03 UTC
  • mfrom: (1.1.3 upstream) (3.1.11 hardy)
  • Revision ID: james.westby@ubuntu.com-20080427102003-qy06c2if0qayzwlg
Tags: 2.7.1-2
* Build-Depends on default-jdk-builddep. Closes: #477893
* Clarified debian/copyright.
* Don't use '-1' in Build-Depends.
* Updated watch file to match upstream correctly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 1999-2004 The Apache Software Foundation.
3
 
 *
4
 
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 
 * you may not use this file except in compliance with the License.
6
 
 * You may obtain a copy of the License at
7
 
 *
8
 
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 
 *
10
 
 * Unless required by applicable law or agreed to in writing, software
11
 
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 
 * See the License for the specific language governing permissions and
14
 
 * limitations under the License.
15
 
 */
16
 
/*
17
 
 * $Id: NumeratorFormatter.java,v 1.8 2004/02/16 20:41:29 minchau Exp $
18
 
 */
19
 
package org.apache.xalan.transformer;
20
 
 
21
 
import java.util.Locale;
22
 
import java.util.NoSuchElementException;
23
 
 
24
 
import org.w3c.dom.Element;
25
 
 
26
 
/**
27
 
 * Converts enumerated numbers into strings, using the XSL conversion attributes.
28
 
 * Having this in a class helps avoid being forced to extract the attributes repeatedly.
29
 
 * @xsl.usage internal
30
 
 */
31
 
class NumeratorFormatter
32
 
{
33
 
 
34
 
  /** The owning xsl:number element.          */
35
 
  protected Element m_xslNumberElement;
36
 
 
37
 
  /** An instance of a Tokenizer          */
38
 
  NumberFormatStringTokenizer m_formatTokenizer;
39
 
 
40
 
  /** Locale we need to format in          */
41
 
  Locale m_locale;
42
 
 
43
 
  /** An instance of a NumberFormat         */
44
 
  java.text.NumberFormat m_formatter;
45
 
 
46
 
  /** An instance of a transformer          */
47
 
  TransformerImpl m_processor;
48
 
 
49
 
  /**
50
 
   * Table to help in converting decimals to roman numerals.
51
 
   * @see org.apache.xalan.transformer.DecimalToRoman
52
 
   */
53
 
  private final static DecimalToRoman m_romanConvertTable[] = {
54
 
    new DecimalToRoman(1000, "M", 900, "CM"),
55
 
    new DecimalToRoman(500, "D", 400, "CD"),
56
 
    new DecimalToRoman(100L, "C", 90L, "XC"),
57
 
    new DecimalToRoman(50L, "L", 40L, "XL"),
58
 
    new DecimalToRoman(10L, "X", 9L, "IX"),
59
 
    new DecimalToRoman(5L, "V", 4L, "IV"),
60
 
    new DecimalToRoman(1L, "I", 1L, "I") };
61
 
 
62
 
  /**
63
 
   * Chars for converting integers into alpha counts.
64
 
   * @see TransformerImpl#int2alphaCount
65
 
   */
66
 
  private final static char[] m_alphaCountTable = { 'Z',  // z for zero
67
 
                                                    'A', 'B', 'C', 'D', 'E',
68
 
                                                    'F', 'G', 'H', 'I', 'J',
69
 
                                                    'K', 'L', 'M', 'N', 'O',
70
 
                                                    'P', 'Q', 'R', 'S', 'T',
71
 
                                                    'U', 'V', 'W', 'X', 'Y' };
72
 
 
73
 
  /**
74
 
   * Construct a NumeratorFormatter using an element
75
 
   * that contains XSL number conversion attributes -
76
 
   * format, letter-value, xml:lang, digit-group-sep,
77
 
   * n-digits-per-group, and sequence-src.
78
 
   *
79
 
   * @param xslNumberElement The given xsl:number element
80
 
   * @param processor a non-null transformer instance
81
 
   */
82
 
  NumeratorFormatter(Element xslNumberElement, TransformerImpl processor)
83
 
  {
84
 
    m_xslNumberElement = xslNumberElement;
85
 
    m_processor = processor;
86
 
  }  // end NumeratorFormatter(Element) constructor
87
 
 
88
 
  /**
89
 
   * Convert a long integer into alphabetic counting, in other words
90
 
   * count using the sequence A B C ... Z AA AB AC.... etc.
91
 
   * 
92
 
   * @param val Value to convert -- must be greater than zero.
93
 
   * @param table a table containing one character for each digit in the radix
94
 
   * @return String representing alpha count of number.
95
 
   * @see org.apache.xalan.transformer.DecimalToRoman
96
 
   *
97
 
   * Note that the radix of the conversion is inferred from the size
98
 
   * of the table.
99
 
   */
100
 
  protected String int2alphaCount(int val, char[] table)
101
 
  {
102
 
 
103
 
    int radix = table.length;
104
 
 
105
 
    // Create a buffer to hold the result
106
 
    // TODO:  size of the table can be detereined by computing
107
 
    // logs of the radix.  For now, we fake it.
108
 
    char buf[] = new char[100];
109
 
 
110
 
    // next character to set in the buffer
111
 
    int charPos = buf.length - 1;  // work backward through buf[]
112
 
 
113
 
    // index in table of the last character that we stored
114
 
    int lookupIndex = 1;  // start off with anything other than zero to make correction work
115
 
 
116
 
    //                                          Correction number
117
 
    //
118
 
    //  Correction can take on exactly two values:
119
 
    //
120
 
    //          0       if the next character is to be emitted is usual
121
 
    //
122
 
    //      radix - 1
123
 
    //                  if the next char to be emitted should be one less than
124
 
    //                  you would expect
125
 
    //
126
 
    // For example, consider radix 10, where 1="A" and 10="J"
127
 
    //
128
 
    // In this scheme, we count: A, B, C ...   H, I, J (not A0 and certainly
129
 
    // not AJ), A1
130
 
    //
131
 
    // So, how do we keep from emitting AJ for 10?  After correctly emitting the
132
 
    // J, lookupIndex is zero.  We now compute a correction number of 9 (radix-1).
133
 
    // In the following line, we'll compute (val+correction) % radix, which is,
134
 
    // (val+9)/10.  By this time, val is 1, so we compute (1+9) % 10, which
135
 
    // is 10 % 10 or zero.  So, we'll prepare to emit "JJ", but then we'll
136
 
    // later suppress the leading J as representing zero (in the mod system,
137
 
    // it can represent either 10 or zero).  In summary, the correction value of
138
 
    // "radix-1" acts like "-1" when run through the mod operator, but with the
139
 
    // desireable characteristic that it never produces a negative number.
140
 
    int correction = 0;
141
 
 
142
 
    // TODO:  throw error on out of range input
143
 
    do
144
 
    {
145
 
 
146
 
      // most of the correction calculation is explained above,  the reason for the
147
 
      // term after the "|| " is that it correctly propagates carries across
148
 
      // multiple columns.
149
 
      correction =
150
 
        ((lookupIndex == 0) || (correction != 0 && lookupIndex == radix - 1))
151
 
        ? (radix - 1) : 0;
152
 
 
153
 
      // index in "table" of the next char to emit
154
 
      lookupIndex = (val + correction) % radix;
155
 
 
156
 
      // shift input by one "column"
157
 
      val = (val / radix);
158
 
 
159
 
      // if the next value we'd put out would be a leading zero, we're done.
160
 
      if (lookupIndex == 0 && val == 0)
161
 
        break;
162
 
 
163
 
      // put out the next character of output
164
 
      buf[charPos--] = table[lookupIndex];
165
 
    }
166
 
    while (val > 0);
167
 
 
168
 
    return new String(buf, charPos + 1, (buf.length - charPos - 1));
169
 
  }
170
 
 
171
 
  /**
172
 
   * Convert a long integer into roman numerals.
173
 
   * @param val Value to convert.
174
 
   * @param prefixesAreOK true_ to enable prefix notation (e.g. 4 = "IV"),
175
 
   * false_ to disable prefix notation (e.g. 4 = "IIII").
176
 
   * @return Roman numeral string.
177
 
   * @see DecimalToRoman
178
 
   * @see m_romanConvertTable
179
 
   */
180
 
  String long2roman(long val, boolean prefixesAreOK)
181
 
  {
182
 
 
183
 
    if (val <= 0)
184
 
    {
185
 
      return "#E(" + val + ")";
186
 
    }
187
 
 
188
 
    String roman = "";
189
 
    int place = 0;
190
 
 
191
 
    if (val <= 3999L)
192
 
    {
193
 
      do
194
 
      {
195
 
        while (val >= m_romanConvertTable[place].m_postValue)
196
 
        {
197
 
          roman += m_romanConvertTable[place].m_postLetter;
198
 
          val -= m_romanConvertTable[place].m_postValue;
199
 
        }
200
 
 
201
 
        if (prefixesAreOK)
202
 
        {
203
 
          if (val >= m_romanConvertTable[place].m_preValue)
204
 
          {
205
 
            roman += m_romanConvertTable[place].m_preLetter;
206
 
            val -= m_romanConvertTable[place].m_preValue;
207
 
          }
208
 
        }
209
 
 
210
 
        place++;
211
 
      }
212
 
      while (val > 0);
213
 
    }
214
 
    else
215
 
    {
216
 
      roman = "#error";
217
 
    }
218
 
 
219
 
    return roman;
220
 
  }  // end long2roman
221
 
 
222
 
  /**
223
 
   * This class returns tokens using non-alphanumberic
224
 
   * characters as delimiters.
225
 
   */
226
 
  class NumberFormatStringTokenizer
227
 
  {
228
 
 
229
 
    /** Field holding the current position in the string      */
230
 
    private int currentPosition;
231
 
 
232
 
    /** The total length of the string          */
233
 
    private int maxPosition;
234
 
 
235
 
    /** The string to tokenize          */
236
 
    private String str;
237
 
 
238
 
    /**
239
 
     * Construct a NumberFormatStringTokenizer.
240
 
     *
241
 
     * @param str The string to tokenize
242
 
     */
243
 
    NumberFormatStringTokenizer(String str)
244
 
    {
245
 
      this.str = str;
246
 
      maxPosition = str.length();
247
 
    }
248
 
    
249
 
    /**
250
 
     * Reset tokenizer so that nextToken() starts from the beginning. 
251
 
     *
252
 
     */
253
 
    void reset()
254
 
    {
255
 
      currentPosition = 0;
256
 
    }
257
 
 
258
 
    /**
259
 
     * Returns the next token from this string tokenizer.
260
 
     *
261
 
     * @return     the next token from this string tokenizer.
262
 
     * @throws  NoSuchElementException  if there are no more tokens in this
263
 
     *               tokenizer's string.
264
 
     */
265
 
    String nextToken()
266
 
    {
267
 
 
268
 
      if (currentPosition >= maxPosition)
269
 
      {
270
 
        throw new NoSuchElementException();
271
 
      }
272
 
 
273
 
      int start = currentPosition;
274
 
 
275
 
      while ((currentPosition < maxPosition)
276
 
             && Character.isLetterOrDigit(str.charAt(currentPosition)))
277
 
      {
278
 
        currentPosition++;
279
 
      }
280
 
 
281
 
      if ((start == currentPosition)
282
 
              && (!Character.isLetterOrDigit(str.charAt(currentPosition))))
283
 
      {
284
 
        currentPosition++;
285
 
      }
286
 
 
287
 
      return str.substring(start, currentPosition);
288
 
    }
289
 
 
290
 
    /**
291
 
     * Tells if <code>nextToken</code> will throw an exception      * if it is called.
292
 
     *
293
 
     * @return true if <code>nextToken</code> can be called      * without throwing an exception.
294
 
     */
295
 
    boolean hasMoreTokens()
296
 
    {
297
 
      return (currentPosition >= maxPosition) ? false : true;
298
 
    }
299
 
 
300
 
    /**
301
 
     * Calculates the number of times that this tokenizer's
302
 
     * <code>nextToken</code> method can be called before it generates an
303
 
     * exception.
304
 
     *
305
 
     * @return  the number of tokens remaining in the string using the current
306
 
     *          delimiter set.
307
 
     * @see     java.util.StringTokenizer#nextToken()
308
 
     */
309
 
    int countTokens()
310
 
    {
311
 
 
312
 
      int count = 0;
313
 
      int currpos = currentPosition;
314
 
 
315
 
      while (currpos < maxPosition)
316
 
      {
317
 
        int start = currpos;
318
 
 
319
 
        while ((currpos < maxPosition)
320
 
               && Character.isLetterOrDigit(str.charAt(currpos)))
321
 
        {
322
 
          currpos++;
323
 
        }
324
 
 
325
 
        if ((start == currpos)
326
 
                && (Character.isLetterOrDigit(str.charAt(currpos)) == false))
327
 
        {
328
 
          currpos++;
329
 
        }
330
 
 
331
 
        count++;
332
 
      }
333
 
 
334
 
      return count;
335
 
    }
336
 
  }  // end NumberFormatStringTokenizer
337
 
}
 
1
/*
 
2
 * Licensed to the Apache Software Foundation (ASF) under one
 
3
 * or more contributor license agreements. See the NOTICE file
 
4
 * distributed with this work for additional information
 
5
 * regarding copyright ownership. The ASF licenses this file
 
6
 * to you under the Apache License, Version 2.0 (the  "License");
 
7
 * you may not use this file except in compliance with the License.
 
8
 * You may obtain a copy of the License at
 
9
 *
 
10
 *     http://www.apache.org/licenses/LICENSE-2.0
 
11
 *
 
12
 * Unless required by applicable law or agreed to in writing, software
 
13
 * distributed under the License is distributed on an "AS IS" BASIS,
 
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
15
 * See the License for the specific language governing permissions and
 
16
 * limitations under the License.
 
17
 */
 
18
/*
 
19
 * $Id: NumeratorFormatter.java 468645 2006-10-28 06:57:24Z minchau $
 
20
 */
 
21
package org.apache.xalan.transformer;
 
22
 
 
23
import java.util.Locale;
 
24
import java.util.NoSuchElementException;
 
25
 
 
26
import org.w3c.dom.Element;
 
27
 
 
28
/**
 
29
 * Converts enumerated numbers into strings, using the XSL conversion attributes.
 
30
 * Having this in a class helps avoid being forced to extract the attributes repeatedly.
 
31
 * @xsl.usage internal
 
32
 */
 
33
class NumeratorFormatter
 
34
{
 
35
 
 
36
  /** The owning xsl:number element.          */
 
37
  protected Element m_xslNumberElement;
 
38
 
 
39
  /** An instance of a Tokenizer          */
 
40
  NumberFormatStringTokenizer m_formatTokenizer;
 
41
 
 
42
  /** Locale we need to format in          */
 
43
  Locale m_locale;
 
44
 
 
45
  /** An instance of a NumberFormat         */
 
46
  java.text.NumberFormat m_formatter;
 
47
 
 
48
  /** An instance of a transformer          */
 
49
  TransformerImpl m_processor;
 
50
 
 
51
  /**
 
52
   * Table to help in converting decimals to roman numerals.
 
53
   * @see org.apache.xalan.transformer.DecimalToRoman
 
54
   */
 
55
  private final static DecimalToRoman m_romanConvertTable[] = {
 
56
    new DecimalToRoman(1000, "M", 900, "CM"),
 
57
    new DecimalToRoman(500, "D", 400, "CD"),
 
58
    new DecimalToRoman(100L, "C", 90L, "XC"),
 
59
    new DecimalToRoman(50L, "L", 40L, "XL"),
 
60
    new DecimalToRoman(10L, "X", 9L, "IX"),
 
61
    new DecimalToRoman(5L, "V", 4L, "IV"),
 
62
    new DecimalToRoman(1L, "I", 1L, "I") };
 
63
 
 
64
  /**
 
65
   * Chars for converting integers into alpha counts.
 
66
   * @see TransformerImpl#int2alphaCount
 
67
   */
 
68
  private final static char[] m_alphaCountTable = { 'Z',  // z for zero
 
69
                                                    'A', 'B', 'C', 'D', 'E',
 
70
                                                    'F', 'G', 'H', 'I', 'J',
 
71
                                                    'K', 'L', 'M', 'N', 'O',
 
72
                                                    'P', 'Q', 'R', 'S', 'T',
 
73
                                                    'U', 'V', 'W', 'X', 'Y' };
 
74
 
 
75
  /**
 
76
   * Construct a NumeratorFormatter using an element
 
77
   * that contains XSL number conversion attributes -
 
78
   * format, letter-value, xml:lang, digit-group-sep,
 
79
   * n-digits-per-group, and sequence-src.
 
80
   *
 
81
   * @param xslNumberElement The given xsl:number element
 
82
   * @param processor a non-null transformer instance
 
83
   */
 
84
  NumeratorFormatter(Element xslNumberElement, TransformerImpl processor)
 
85
  {
 
86
    m_xslNumberElement = xslNumberElement;
 
87
    m_processor = processor;
 
88
  }  // end NumeratorFormatter(Element) constructor
 
89
 
 
90
  /**
 
91
   * Convert a long integer into alphabetic counting, in other words
 
92
   * count using the sequence A B C ... Z AA AB AC.... etc.
 
93
   * 
 
94
   * @param val Value to convert -- must be greater than zero.
 
95
   * @param table a table containing one character for each digit in the radix
 
96
   * @return String representing alpha count of number.
 
97
   * @see org.apache.xalan.transformer.DecimalToRoman
 
98
   *
 
99
   * Note that the radix of the conversion is inferred from the size
 
100
   * of the table.
 
101
   */
 
102
  protected String int2alphaCount(int val, char[] table)
 
103
  {
 
104
 
 
105
    int radix = table.length;
 
106
 
 
107
    // Create a buffer to hold the result
 
108
    // TODO:  size of the table can be detereined by computing
 
109
    // logs of the radix.  For now, we fake it.
 
110
    char buf[] = new char[100];
 
111
 
 
112
    // next character to set in the buffer
 
113
    int charPos = buf.length - 1;  // work backward through buf[]
 
114
 
 
115
    // index in table of the last character that we stored
 
116
    int lookupIndex = 1;  // start off with anything other than zero to make correction work
 
117
 
 
118
    //                                          Correction number
 
119
    //
 
120
    //  Correction can take on exactly two values:
 
121
    //
 
122
    //          0       if the next character is to be emitted is usual
 
123
    //
 
124
    //      radix - 1
 
125
    //                  if the next char to be emitted should be one less than
 
126
    //                  you would expect
 
127
    //
 
128
    // For example, consider radix 10, where 1="A" and 10="J"
 
129
    //
 
130
    // In this scheme, we count: A, B, C ...   H, I, J (not A0 and certainly
 
131
    // not AJ), A1
 
132
    //
 
133
    // So, how do we keep from emitting AJ for 10?  After correctly emitting the
 
134
    // J, lookupIndex is zero.  We now compute a correction number of 9 (radix-1).
 
135
    // In the following line, we'll compute (val+correction) % radix, which is,
 
136
    // (val+9)/10.  By this time, val is 1, so we compute (1+9) % 10, which
 
137
    // is 10 % 10 or zero.  So, we'll prepare to emit "JJ", but then we'll
 
138
    // later suppress the leading J as representing zero (in the mod system,
 
139
    // it can represent either 10 or zero).  In summary, the correction value of
 
140
    // "radix-1" acts like "-1" when run through the mod operator, but with the
 
141
    // desireable characteristic that it never produces a negative number.
 
142
    int correction = 0;
 
143
 
 
144
    // TODO:  throw error on out of range input
 
145
    do
 
146
    {
 
147
 
 
148
      // most of the correction calculation is explained above,  the reason for the
 
149
      // term after the "|| " is that it correctly propagates carries across
 
150
      // multiple columns.
 
151
      correction =
 
152
        ((lookupIndex == 0) || (correction != 0 && lookupIndex == radix - 1))
 
153
        ? (radix - 1) : 0;
 
154
 
 
155
      // index in "table" of the next char to emit
 
156
      lookupIndex = (val + correction) % radix;
 
157
 
 
158
      // shift input by one "column"
 
159
      val = (val / radix);
 
160
 
 
161
      // if the next value we'd put out would be a leading zero, we're done.
 
162
      if (lookupIndex == 0 && val == 0)
 
163
        break;
 
164
 
 
165
      // put out the next character of output
 
166
      buf[charPos--] = table[lookupIndex];
 
167
    }
 
168
    while (val > 0);
 
169
 
 
170
    return new String(buf, charPos + 1, (buf.length - charPos - 1));
 
171
  }
 
172
 
 
173
  /**
 
174
   * Convert a long integer into roman numerals.
 
175
   * @param val Value to convert.
 
176
   * @param prefixesAreOK true_ to enable prefix notation (e.g. 4 = "IV"),
 
177
   * false_ to disable prefix notation (e.g. 4 = "IIII").
 
178
   * @return Roman numeral string.
 
179
   * @see DecimalToRoman
 
180
   * @see m_romanConvertTable
 
181
   */
 
182
  String long2roman(long val, boolean prefixesAreOK)
 
183
  {
 
184
 
 
185
    if (val <= 0)
 
186
    {
 
187
      return "#E(" + val + ")";
 
188
    }
 
189
 
 
190
    String roman = "";
 
191
    int place = 0;
 
192
 
 
193
    if (val <= 3999L)
 
194
    {
 
195
      do
 
196
      {
 
197
        while (val >= m_romanConvertTable[place].m_postValue)
 
198
        {
 
199
          roman += m_romanConvertTable[place].m_postLetter;
 
200
          val -= m_romanConvertTable[place].m_postValue;
 
201
        }
 
202
 
 
203
        if (prefixesAreOK)
 
204
        {
 
205
          if (val >= m_romanConvertTable[place].m_preValue)
 
206
          {
 
207
            roman += m_romanConvertTable[place].m_preLetter;
 
208
            val -= m_romanConvertTable[place].m_preValue;
 
209
          }
 
210
        }
 
211
 
 
212
        place++;
 
213
      }
 
214
      while (val > 0);
 
215
    }
 
216
    else
 
217
    {
 
218
      roman = "#error";
 
219
    }
 
220
 
 
221
    return roman;
 
222
  }  // end long2roman
 
223
 
 
224
  /**
 
225
   * This class returns tokens using non-alphanumberic
 
226
   * characters as delimiters.
 
227
   */
 
228
  class NumberFormatStringTokenizer
 
229
  {
 
230
 
 
231
    /** Field holding the current position in the string      */
 
232
    private int currentPosition;
 
233
 
 
234
    /** The total length of the string          */
 
235
    private int maxPosition;
 
236
 
 
237
    /** The string to tokenize          */
 
238
    private String str;
 
239
 
 
240
    /**
 
241
     * Construct a NumberFormatStringTokenizer.
 
242
     *
 
243
     * @param str The string to tokenize
 
244
     */
 
245
    NumberFormatStringTokenizer(String str)
 
246
    {
 
247
      this.str = str;
 
248
      maxPosition = str.length();
 
249
    }
 
250
    
 
251
    /**
 
252
     * Reset tokenizer so that nextToken() starts from the beginning. 
 
253
     *
 
254
     */
 
255
    void reset()
 
256
    {
 
257
      currentPosition = 0;
 
258
    }
 
259
 
 
260
    /**
 
261
     * Returns the next token from this string tokenizer.
 
262
     *
 
263
     * @return     the next token from this string tokenizer.
 
264
     * @throws  NoSuchElementException  if there are no more tokens in this
 
265
     *               tokenizer's string.
 
266
     */
 
267
    String nextToken()
 
268
    {
 
269
 
 
270
      if (currentPosition >= maxPosition)
 
271
      {
 
272
        throw new NoSuchElementException();
 
273
      }
 
274
 
 
275
      int start = currentPosition;
 
276
 
 
277
      while ((currentPosition < maxPosition)
 
278
             && Character.isLetterOrDigit(str.charAt(currentPosition)))
 
279
      {
 
280
        currentPosition++;
 
281
      }
 
282
 
 
283
      if ((start == currentPosition)
 
284
              && (!Character.isLetterOrDigit(str.charAt(currentPosition))))
 
285
      {
 
286
        currentPosition++;
 
287
      }
 
288
 
 
289
      return str.substring(start, currentPosition);
 
290
    }
 
291
 
 
292
    /**
 
293
     * Tells if <code>nextToken</code> will throw an exception      * if it is called.
 
294
     *
 
295
     * @return true if <code>nextToken</code> can be called      * without throwing an exception.
 
296
     */
 
297
    boolean hasMoreTokens()
 
298
    {
 
299
      return (currentPosition >= maxPosition) ? false : true;
 
300
    }
 
301
 
 
302
    /**
 
303
     * Calculates the number of times that this tokenizer's
 
304
     * <code>nextToken</code> method can be called before it generates an
 
305
     * exception.
 
306
     *
 
307
     * @return  the number of tokens remaining in the string using the current
 
308
     *          delimiter set.
 
309
     * @see     java.util.StringTokenizer#nextToken()
 
310
     */
 
311
    int countTokens()
 
312
    {
 
313
 
 
314
      int count = 0;
 
315
      int currpos = currentPosition;
 
316
 
 
317
      while (currpos < maxPosition)
 
318
      {
 
319
        int start = currpos;
 
320
 
 
321
        while ((currpos < maxPosition)
 
322
               && Character.isLetterOrDigit(str.charAt(currpos)))
 
323
        {
 
324
          currpos++;
 
325
        }
 
326
 
 
327
        if ((start == currpos)
 
328
                && (Character.isLetterOrDigit(str.charAt(currpos)) == false))
 
329
        {
 
330
          currpos++;
 
331
        }
 
332
 
 
333
        count++;
 
334
      }
 
335
 
 
336
      return count;
 
337
    }
 
338
  }  // end NumberFormatStringTokenizer
 
339
}