OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [text/] [FormatCharacterIterator.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* FormatCharacter.java -- Implementation of AttributedCharacterIterator for
2
   formatters.
3
   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
4
 
5
This file is part of GNU Classpath.
6
 
7
GNU Classpath is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
10
any later version.
11
 
12
GNU Classpath is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GNU Classpath; see the file COPYING.  If not, write to the
19
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301 USA.
21
 
22
Linking this library statically or dynamically with other modules is
23
making a combined work based on this library.  Thus, the terms and
24
conditions of the GNU General Public License cover the whole
25
combination.
26
 
27
As a special exception, the copyright holders of this library give you
28
permission to link this library with independent modules to produce an
29
executable, regardless of the license terms of these independent
30
modules, and to copy and distribute the resulting executable under
31
terms of your choice, provided that you also meet, for each linked
32
independent module, the terms and conditions of the license of that
33
module.  An independent module is a module which is not derived from
34
or based on this library.  If you modify this library, you may extend
35
this exception to your version of the library, but you are not
36
obligated to do so.  If you do not wish to do so, delete this
37
exception statement from your version. */
38
package gnu.java.text;
39
 
40
import java.text.AttributedCharacterIterator;
41
import java.util.HashMap;
42
import java.util.HashSet;
43
import java.util.Iterator;
44
import java.util.Map;
45
import java.util.Set;
46
import java.util.Vector;
47
 
48
/**
49
 * This class should not be put public and it is only intended to the
50
 * classes of the java.text package. Its aim is to build a segmented
51
 * character iterator by appending strings and adding attributes to
52
 * portions of strings. The code intends to do some optimization
53
 * concerning memory consumption and attribute access but at the
54
 * end it is only an AttributedCharacterIterator.
55
 *
56
 * @author Guilhem Lavaux <guilhem@kaffe.org>
57
 * @date November 22, 2003
58
 */
59
public class FormatCharacterIterator implements AttributedCharacterIterator
60
{
61
  private String formattedString;
62
  private int charIndex;
63
  private int attributeIndex;
64
  private int[] ranges;
65
  private HashMap[] attributes;
66
  private static final boolean DEBUG = false;
67
 
68
  /**
69
   * This constructor builds an empty iterated strings. The attributes
70
   * are empty and so is the string. However you may append strings
71
   * and attributes to this iterator.
72
   */
73
  public FormatCharacterIterator()
74
  {
75
    formattedString = "";
76
    ranges = new int[0];
77
    attributes = new HashMap[0];
78
  }
79
 
80
  /**
81
   * This constructor take a string <code>s</code>, a set of ranges
82
   * and the corresponding attributes. This is used to build an iterator.
83
   * The array <code>ranges</code> should be formatted as follow:
84
   * each element of <code>ranges</code> specifies the index in the string
85
   * until which the corresponding map of attributes at the same position
86
   * is applied. For example, if you have:
87
   * <pre>
88
   *   s = "hello";
89
   *   ranges = new int[] { 2, 6 };
90
   *   attributes = new HashMap[2];
91
   * </pre>
92
   * <code>"he"</code> will have the attributes <code>attributes[0]</code>,
93
   * <code>"llo"</code> the <code>attributes[1]</code>.
94
   */
95
  public FormatCharacterIterator (String s, int[] ranges, HashMap[] attributes)
96
  {
97
    formattedString = s;
98
    this.ranges = ranges;
99
    this.attributes = attributes;
100
  }
101
 
102
  /*
103
   * The following methods are inherited from AttributedCharacterIterator,
104
   * and thus are already documented.
105
   */
106
 
107
  public Set getAllAttributeKeys()
108
  {
109
    if (attributes != null && attributes[attributeIndex] != null)
110
      return attributes[attributeIndex].keySet();
111
    else
112
      return new HashSet();
113
  }
114
 
115
  public Map getAttributes()
116
  {
117
    if (attributes != null && attributes[attributeIndex] != null)
118
      return attributes[attributeIndex];
119
    else
120
      return new HashMap();
121
  }
122
 
123
  public Object getAttribute (AttributedCharacterIterator.Attribute attrib)
124
  {
125
    if (attributes != null && attributes[attributeIndex] != null)
126
      return attributes[attributeIndex].get (attrib);
127
    else
128
      return null;
129
  }
130
 
131
  public int getRunLimit(Set reqAttrs)
132
  {
133
    if (attributes == null)
134
      return formattedString.length();
135
 
136
    int currentAttrIndex = attributeIndex;
137
    Set newKeys;
138
 
139
    do
140
      {
141
        currentAttrIndex++;
142
        if (currentAttrIndex == attributes.length)
143
          return formattedString.length();
144
        if (attributes[currentAttrIndex] == null)
145
          break;
146
        newKeys = attributes[currentAttrIndex].keySet();
147
      }
148
    while (newKeys.containsAll (reqAttrs));
149
 
150
    return ranges[currentAttrIndex-1];
151
  }
152
 
153
  public int getRunLimit (AttributedCharacterIterator.Attribute attribute)
154
  {
155
    Set s = new HashSet();
156
 
157
    s.add (attribute);
158
    return getRunLimit (s);
159
  }
160
 
161
  public int getRunLimit()
162
  {
163
    if (attributes == null)
164
      return formattedString.length();
165
    if (attributes[attributeIndex] == null)
166
      {
167
        for (int i=attributeIndex+1;i<attributes.length;i++)
168
          if (attributes[i] != null)
169
            return ranges[i-1];
170
        return formattedString.length();
171
      }
172
 
173
    return getRunLimit (attributes[attributeIndex].keySet());
174
  }
175
 
176
  public int getRunStart (Set reqAttrs)
177
  {
178
    if (attributes == null)
179
      return formattedString.length();
180
 
181
    int currentAttrIndex = attributeIndex;
182
    Set newKeys = null;
183
 
184
    do
185
      {
186
        if (currentAttrIndex == 0)
187
          return 0;
188
 
189
        currentAttrIndex--;
190
        if (attributes[currentAttrIndex] == null)
191
          break;
192
        newKeys = attributes[currentAttrIndex].keySet();
193
      }
194
    while (newKeys.containsAll (reqAttrs));
195
 
196
    return (currentAttrIndex > 0) ? ranges[currentAttrIndex-1] : 0;
197
  }
198
 
199
  public int getRunStart()
200
  {
201
    if (attributes == null)
202
      return 0;
203
 
204
    if (attributes[attributeIndex] == null)
205
      {
206
        for (int i=attributeIndex;i>0;i--)
207
          if (attributes[i] != null)
208
            return ranges[attributeIndex-1];
209
        return 0;
210
      }
211
 
212
    return getRunStart (attributes[attributeIndex].keySet());
213
  }
214
 
215
  public int getRunStart (AttributedCharacterIterator.Attribute attribute)
216
  {
217
    Set s = new HashSet();
218
 
219
    s.add (attribute);
220
    return getRunStart (s);
221
  }
222
 
223
  public Object clone()
224
  {
225
    return new FormatCharacterIterator (formattedString, ranges, attributes);
226
  }
227
 
228
  /*
229
   * The following methods are inherited from CharacterIterator and thus
230
   * are already documented.
231
   */
232
 
233
  public char current()
234
  {
235
    return formattedString.charAt (charIndex);
236
  }
237
 
238
  public char first()
239
  {
240
    charIndex = 0;
241
    attributeIndex = 0;
242
    return formattedString.charAt (0);
243
  }
244
 
245
  public int getBeginIndex()
246
  {
247
    return 0;
248
  }
249
 
250
  public int getEndIndex()
251
  {
252
    return formattedString.length();
253
  }
254
 
255
  public int getIndex()
256
  {
257
    return charIndex;
258
  }
259
 
260
  public char last()
261
  {
262
    charIndex = formattedString.length()-1;
263
    if (attributes != null)
264
      attributeIndex = attributes.length-1;
265
    return formattedString.charAt (charIndex);
266
  }
267
 
268
  public char next()
269
  {
270
    charIndex++;
271
    if (charIndex >= formattedString.length())
272
      {
273
        charIndex = getEndIndex();
274
        return DONE;
275
      }
276
    if (attributes != null)
277
      {
278
        if (charIndex >= ranges[attributeIndex])
279
          attributeIndex++;
280
      }
281
    return formattedString.charAt (charIndex);
282
  }
283
 
284
  public char previous()
285
  {
286
    charIndex--;
287
    if (charIndex < 0)
288
      {
289
        charIndex = 0;
290
        return DONE;
291
      }
292
 
293
    if (attributes != null)
294
      {
295
        if (charIndex < ranges[attributeIndex])
296
          attributeIndex--;
297
      }
298
    return formattedString.charAt (charIndex);
299
  }
300
 
301
  public char setIndex (int position)
302
  {
303
    if (position < 0 || position > formattedString.length())
304
      throw new IllegalArgumentException ("position is out of range");
305
 
306
    charIndex = position;
307
    if (attributes != null)
308
      {
309
        for (attributeIndex=0;attributeIndex<attributes.length;
310
             attributeIndex++)
311
          if (ranges[attributeIndex] > charIndex)
312
            break;
313
        attributeIndex--;
314
      }
315
    if (charIndex == formattedString.length())
316
      return DONE;
317
    else
318
      return formattedString.charAt (charIndex);
319
  }
320
 
321
  /**
322
   * This method merge the specified attributes and ranges with the
323
   * internal tables. This method is in charge of the optimization
324
   * of tables. Two following sets of attributes are never the same.
325
   *
326
   * @see #FormatCharacterIterator()
327
   *
328
   * @param attributes the new array attributes to apply to the string.
329
   */
330
  public void mergeAttributes (HashMap[] attributes, int[] ranges)
331
  {
332
    Vector new_ranges = new Vector();
333
    Vector new_attributes = new Vector();
334
    int i = 0, j = 0;
335
 
336
    debug("merging " + attributes.length + " attrs");
337
 
338
    while (i < this.ranges.length && j < ranges.length)
339
      {
340
        if (this.attributes[i] != null)
341
          {
342
            new_attributes.add (this.attributes[i]);
343
            if (attributes[j] != null)
344
              this.attributes[i].putAll (attributes[j]);
345
          }
346
        else
347
          {
348
            new_attributes.add (attributes[j]);
349
          }
350
        if (this.ranges[i] == ranges[j])
351
          {
352
            new_ranges.add (new Integer (ranges[j]));
353
            i++;
354
            j++;
355
          }
356
        else if (this.ranges[i] < ranges[j])
357
          {
358
            new_ranges.add (new Integer (this.ranges[i]));
359
            i++;
360
          }
361
        else
362
          {
363
            new_ranges.add (new Integer (ranges[j]));
364
            j++;
365
          }
366
     }
367
 
368
    if (i != this.ranges.length)
369
      {
370
        for (;i<this.ranges.length;i++)
371
          {
372
            new_attributes.add (this.attributes[i]);
373
            new_ranges.add (new Integer (this.ranges[i]));
374
          }
375
      }
376
    if (j != ranges.length)
377
      {
378
        for (;j<ranges.length;j++)
379
          {
380
            new_attributes.add (attributes[j]);
381
            new_ranges.add (new Integer (ranges[j]));
382
          }
383
      }
384
 
385
    this.attributes = new HashMap[new_attributes.size()];
386
    this.ranges = new int[new_ranges.size()];
387
    System.arraycopy (new_attributes.toArray(), 0, this.attributes,
388
                      0, this.attributes.length);
389
 
390
    for (i=0;i<new_ranges.size();i++)
391
      {
392
        this.ranges[i] = ((Integer)new_ranges.elementAt (i)).intValue();
393
      }
394
 
395
    dumpTable();
396
  }
397
 
398
  /**
399
   * This method appends to the internal attributed string the attributed
400
   * string contained in the specified iterator.
401
   *
402
   * @param iterator the iterator which contains the attributed string to
403
   * append to this iterator.
404
   */
405
  public void append (AttributedCharacterIterator iterator)
406
  {
407
    char c = iterator.first();
408
    Vector more_ranges = new Vector();
409
    Vector more_attributes = new Vector();
410
 
411
    do
412
      {
413
        formattedString = formattedString + String.valueOf (c);
414
        // TODO: Reduce the size of the output array.
415
        more_attributes.add (iterator.getAttributes());
416
        more_ranges.add (new Integer (formattedString.length()));
417
        // END TOOD
418
        c = iterator.next();
419
      }
420
    while (c != DONE);
421
 
422
    HashMap[] new_attributes = new HashMap[attributes.length
423
                                           + more_attributes.size()];
424
    int[] new_ranges = new int[ranges.length + more_ranges.size()];
425
 
426
    System.arraycopy (attributes, 0, new_attributes, 0, attributes.length);
427
    System.arraycopy (more_attributes.toArray(), 0, new_attributes,
428
                      attributes.length, more_attributes.size());
429
 
430
    System.arraycopy (ranges, 0, new_ranges, 0, ranges.length);
431
    Object[] new_ranges_array = more_ranges.toArray();
432
    for (int i = 0; i < more_ranges.size();i++)
433
      new_ranges[i+ranges.length] = ((Integer) new_ranges_array[i]).intValue();
434
 
435
    attributes = new_attributes;
436
    ranges = new_ranges;
437
  }
438
 
439
  /**
440
   * This method appends an attributed string which attributes are specified
441
   * directly in the calling parameters.
442
   *
443
   * @param text The string to append.
444
   * @param local_attributes The attributes to put on this string in the
445
   * iterator. If it is <code>null</code> the string will simply have no
446
   * attributes.
447
   */
448
  public void append (String text, HashMap local_attributes)
449
  {
450
    int[] new_ranges = new int[ranges.length+1];
451
    HashMap[] new_attributes = new HashMap[attributes.length+1];
452
 
453
    formattedString += text;
454
    System.arraycopy (attributes, 0, new_attributes, 0, attributes.length);
455
    System.arraycopy (ranges, 0, new_ranges, 0, ranges.length);
456
    new_ranges[ranges.length] = formattedString.length();
457
    new_attributes[attributes.length] = local_attributes;
458
 
459
    ranges = new_ranges;
460
    attributes = new_attributes;
461
  }
462
 
463
  /**
464
   * This method appends a string without attributes. It is completely
465
   * equivalent to call {@link #append(String,HashMap)} with local_attributes
466
   * equal to <code>null</code>.
467
   *
468
   * @param text The string to append to the iterator.
469
   */
470
  public void append (String text)
471
  {
472
    append (text, null);
473
  }
474
 
475
  /**
476
   * This method adds a set of attributes to a range of character. The
477
   * bounds are always inclusive. In the case many attributes have to
478
   * be added it is advised to directly use {@link #mergeAttributes([Ljava.util.HashMap;[I}
479
   *
480
   * @param attributes Attributes to merge into the iterator.
481
   * @param range_start Lower bound of the range of characters which will receive the
482
   * attribute.
483
   * @param range_end Upper bound of the range of characters which will receive the
484
   * attribute.
485
   *
486
   * @throws IllegalArgumentException if ranges are out of bounds.
487
   */
488
  public void addAttributes(HashMap attributes, int range_start, int range_end)
489
  {
490
    if (range_start == 0)
491
      mergeAttributes(new HashMap[] { attributes }, new int[] { range_end });
492
    else
493
      mergeAttributes(new HashMap[] { null, attributes }, new int[] { range_start, range_end });
494
  }
495
 
496
  private void debug(String s)
497
  {
498
    if (DEBUG)
499
      System.out.println(s);
500
  }
501
 
502
  private void dumpTable()
503
  {
504
    int start_range = 0;
505
 
506
    if (!DEBUG)
507
      return;
508
 
509
    System.out.println("Dumping internal table:");
510
    for (int i = 0; i < ranges.length; i++)
511
      {
512
        System.out.print("\t" + start_range + " => " + ranges[i] + ":");
513
        if (attributes[i] == null)
514
          System.out.println("null");
515
        else
516
          {
517
            Set keyset = attributes[i].keySet();
518
            if (keyset != null)
519
              {
520
                Iterator keys = keyset.iterator();
521
 
522
                while (keys.hasNext())
523
                  System.out.print(" " + keys.next());
524
              }
525
            else
526
              System.out.println("keySet null");
527
            System.out.println();
528
          }
529
      }
530
    System.out.println();
531
    System.out.flush();
532
  }
533
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.