FormatCharacterIterator.java [plain text]
package gnu.java.text;
import gnu.classpath.Configuration;
import java.text.AttributedCharacterIterator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
public class FormatCharacterIterator implements AttributedCharacterIterator
{
private String formattedString;
private int charIndex;
private int attributeIndex;
private int[] ranges;
private HashMap[] attributes;
public FormatCharacterIterator()
{
formattedString = "";
ranges = new int[0];
attributes = new HashMap[0];
}
public FormatCharacterIterator (String s, int[] ranges, HashMap[] attributes)
{
formattedString = s;
this.ranges = ranges;
this.attributes = attributes;
}
public Set getAllAttributeKeys()
{
if (attributes != null && attributes[attributeIndex] != null)
return attributes[attributeIndex].keySet();
else
return new HashSet();
}
public Map getAttributes()
{
if (attributes != null && attributes[attributeIndex] != null)
return attributes[attributeIndex];
else
return new HashMap();
}
public Object getAttribute (AttributedCharacterIterator.Attribute attrib)
{
if (attributes != null && attributes[attributeIndex] != null)
return attributes[attributeIndex].get (attrib);
else
return null;
}
public int getRunLimit(Set reqAttrs)
{
if (attributes == null)
return formattedString.length();
int currentAttrIndex = attributeIndex;
Set newKeys;
do
{
currentAttrIndex++;
if (currentAttrIndex == attributes.length)
return formattedString.length();
if (attributes[currentAttrIndex] == null)
break;
newKeys = attributes[currentAttrIndex].keySet();
}
while (newKeys.containsAll (reqAttrs));
return ranges[currentAttrIndex-1];
}
public int getRunLimit (AttributedCharacterIterator.Attribute attribute)
{
Set s = new HashSet();
s.add (attribute);
return getRunLimit (s);
}
public int getRunLimit()
{
if (attributes == null)
return formattedString.length();
if (attributes[attributeIndex] == null)
{
for (int i=attributeIndex+1;i<attributes.length;i++)
if (attributes[i] != null)
return ranges[i-1];
return formattedString.length();
}
return getRunLimit (attributes[attributeIndex].keySet());
}
public int getRunStart (Set reqAttrs)
{
if (attributes == null)
return formattedString.length();
int currentAttrIndex = attributeIndex;
Set newKeys = null;
do
{
if (currentAttrIndex == 0)
return 0;
currentAttrIndex--;
if (attributes[currentAttrIndex] == null)
break;
newKeys = attributes[currentAttrIndex].keySet();
}
while (newKeys.containsAll (reqAttrs));
return (currentAttrIndex > 0) ? ranges[currentAttrIndex-1] : 0;
}
public int getRunStart()
{
if (attributes == null)
return 0;
if (attributes[attributeIndex] == null)
{
for (int i=attributeIndex;i>0;i--)
if (attributes[i] != null)
return ranges[attributeIndex-1];
return 0;
}
return getRunStart (attributes[attributeIndex].keySet());
}
public int getRunStart (AttributedCharacterIterator.Attribute attribute)
{
Set s = new HashSet();
s.add (attribute);
return getRunStart (s);
}
public Object clone()
{
return new FormatCharacterIterator (formattedString, ranges, attributes);
}
public char current()
{
return formattedString.charAt (charIndex);
}
public char first()
{
charIndex = 0;
attributeIndex = 0;
return formattedString.charAt (0);
}
public int getBeginIndex()
{
return 0;
}
public int getEndIndex()
{
return formattedString.length();
}
public int getIndex()
{
return charIndex;
}
public char last()
{
charIndex = formattedString.length()-1;
if (attributes != null)
attributeIndex = attributes.length-1;
return formattedString.charAt (charIndex);
}
public char next()
{
charIndex++;
if (charIndex >= formattedString.length())
{
charIndex = getEndIndex();
return DONE;
}
if (attributes != null)
{
if (charIndex >= ranges[attributeIndex])
attributeIndex++;
}
return formattedString.charAt (charIndex);
}
public char previous()
{
charIndex--;
if (charIndex < 0)
{
charIndex = 0;
return DONE;
}
if (attributes != null)
{
if (charIndex < ranges[attributeIndex])
attributeIndex--;
}
return formattedString.charAt (charIndex);
}
public char setIndex (int position)
{
if (position < 0 || position > formattedString.length())
throw new IllegalArgumentException ("position is out of range");
charIndex = position;
if (attributes != null)
{
for (attributeIndex=0;attributeIndex<attributes.length;
attributeIndex++)
if (ranges[attributeIndex] > charIndex)
break;
attributeIndex--;
}
if (charIndex == formattedString.length())
return DONE;
else
return formattedString.charAt (charIndex);
}
public void mergeAttributes (HashMap[] attributes, int[] ranges)
{
Vector new_ranges = new Vector();
Vector new_attributes = new Vector();
int i = 0, j = 0;
debug("merging " + attributes.length + " attrs");
while (i < this.ranges.length && j < ranges.length)
{
if (this.attributes[i] != null)
{
new_attributes.add (this.attributes[i]);
if (attributes[j] != null)
this.attributes[i].putAll (attributes[j]);
}
else
{
new_attributes.add (attributes[j]);
}
if (this.ranges[i] == ranges[j])
{
new_ranges.add (new Integer (ranges[j]));
i++;
j++;
}
else if (this.ranges[i] < ranges[j])
{
new_ranges.add (new Integer (this.ranges[i]));
i++;
}
else
{
new_ranges.add (new Integer (ranges[j]));
j++;
}
}
if (i != this.ranges.length)
{
for (;i<this.ranges.length;i++)
{
new_attributes.add (this.attributes[i]);
new_ranges.add (new Integer (this.ranges[i]));
}
}
if (j != ranges.length)
{
for (;j<ranges.length;j++)
{
new_attributes.add (attributes[j]);
new_ranges.add (new Integer (ranges[j]));
}
}
this.attributes = new HashMap[new_attributes.size()];
this.ranges = new int[new_ranges.size()];
System.arraycopy (new_attributes.toArray(), 0, this.attributes,
0, this.attributes.length);
for (i=0;i<new_ranges.size();i++)
{
this.ranges[i] = ((Integer)new_ranges.elementAt (i)).intValue();
}
dumpTable();
}
public void append (AttributedCharacterIterator iterator)
{
char c = iterator.first();
Vector more_ranges = new Vector();
Vector more_attributes = new Vector();
do
{
formattedString = formattedString + String.valueOf (c);
more_attributes.add (iterator.getAttributes());
more_ranges.add (new Integer (formattedString.length()));
c = iterator.next();
}
while (c != DONE);
HashMap[] new_attributes = new HashMap[attributes.length
+ more_attributes.size()];
int[] new_ranges = new int[ranges.length + more_ranges.size()];
System.arraycopy (attributes, 0, new_attributes, 0, attributes.length);
System.arraycopy (more_attributes.toArray(), 0, new_attributes,
attributes.length, more_attributes.size());
System.arraycopy (ranges, 0, new_ranges, 0, ranges.length);
Object[] new_ranges_array = more_ranges.toArray();
for (int i = 0; i < more_ranges.size();i++)
new_ranges[i+ranges.length] = ((Integer) new_ranges_array[i]).intValue();
attributes = new_attributes;
ranges = new_ranges;
}
public void append (String text, HashMap local_attributes)
{
int[] new_ranges = new int[ranges.length+1];
HashMap[] new_attributes = new HashMap[attributes.length+1];
formattedString += text;
System.arraycopy (attributes, 0, new_attributes, 0, attributes.length);
System.arraycopy (ranges, 0, new_ranges, 0, ranges.length);
new_ranges[ranges.length] = formattedString.length();
new_attributes[attributes.length] = local_attributes;
ranges = new_ranges;
attributes = new_attributes;
}
public void append (String text)
{
append (text, null);
}
public void addAttributes(HashMap attributes, int range_start, int range_end)
{
if (range_start == 0)
mergeAttributes(new HashMap[] { attributes }, new int[] { range_end });
else
mergeAttributes(new HashMap[] { null, attributes }, new int[] { range_start, range_end });
}
private void debug(String s)
{
if (Configuration.DEBUG)
System.out.println(s);
}
private void dumpTable()
{
int start_range = 0;
if (!Configuration.DEBUG)
return;
System.out.println("Dumping internal table:");
for (int i = 0; i < ranges.length; i++)
{
System.out.print("\t" + start_range + " => " + ranges[i] + ":");
if (attributes[i] == null)
System.out.println("null");
else
{
Set keyset = attributes[i].keySet();
if (keyset != null)
{
Iterator keys = keyset.iterator();
while (keys.hasNext())
System.out.print(" " + keys.next());
}
else
System.out.println("keySet null");
System.out.println();
}
}
System.out.println();
System.out.flush();
}
}