acoliver 2002/11/07 18:34:08
Modified: src/java/org/apache/poi/hssf/record UnicodeString.java
src/java/org/apache/poi/util HexRead.java StringUtil.java
src/testcases/org/apache/poi/util TestStringUtil.java
Log:
think I may have fixed the encoding thing... maybe..... I hope..
Revision Changes Path
1.6 +406 -399
jakarta-poi/src/java/org/apache/poi/hssf/record/UnicodeString.java
Index: UnicodeString.java
===================================================================
RCS file:
/home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/UnicodeString.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- UnicodeString.java 26 Jun 2002 12:25:44 -0000 1.5
+++ UnicodeString.java 8 Nov 2002 02:34:08 -0000 1.6
@@ -1,399 +1,406 @@
-
-/* ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2002 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Apache" and "Apache Software Foundation" and
- * "Apache POI" must not be used to endorse or promote products
- * derived from this software without prior written permission. For
- * written permission, please contact [EMAIL PROTECTED]
- *
- * 5. Products derived from this software may not be called "Apache",
- * "Apache POI", nor may "Apache" appear in their name, without
- * prior written permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.poi.hssf.record;
-
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.StringUtil;
-
-/**
- * Title: Unicode String<P>
- * Description: Unicode String record. We implement these as a record, although
- * they are really just standard fields that are in several records.
- * It is considered more desirable then repeating it in all of
them.<P>
- * REFERENCE: PG 264 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
- * @author Andrew C. Oliver
- * @author Marc Johnson (mjohnson at apache dot org)
- * @author Glen Stampoultzis (glens at apache.org)
- * @version 2.0-pre
- */
-
-public class UnicodeString
- extends Record
- implements Comparable
-{
- public final static short sid = 0xFFF;
- private short field_1_charCount; // = 0;
- private byte field_2_optionflags; // = 0;
- private String field_3_string; // = null;
- private final int RICH_TEXT_BIT = 8;
- private final int EXT_BIT = 4;
-
- public UnicodeString()
- {
- }
-
-
- public int hashCode()
- {
- int stringHash = 0;
- if (field_3_string != null)
- stringHash = field_3_string.hashCode();
- return field_1_charCount + stringHash;
- }
-
- /**
- * Our handling of equals is inconsistent with compareTo. The trouble is
because we don't truely understand
- * rich text fields yet it's difficult to make a sound comparison.
- *
- * @param o The object to compare.
- * @return true if the object is actually equal.
- */
- public boolean equals(Object o)
- {
- if ((o == null) || (o.getClass() != this.getClass()))
- {
- return false;
- }
- UnicodeString other = ( UnicodeString ) o;
-
- return ((field_1_charCount == other.field_1_charCount)
- && (field_2_optionflags == other.field_2_optionflags)
- && field_3_string.equals(other.field_3_string));
- }
-
- /**
- * construct a unicode string record and fill its fields, ID is ignored
- * @param id - ignored
- * @param size - size of the data
- * @param data - the bytes of the string/fields
- */
-
- public UnicodeString(short id, short size, byte [] data)
- {
- super(id, size, data);
- }
-
- /**
- * construct a unicode string from a string fragment + data
- */
-
- public UnicodeString(short id, short size, byte [] data, String prefix)
- {
- this(id, size, data);
- field_3_string = prefix + field_3_string;
- setCharCount();
- }
-
- /**
- * NO OP
- */
-
- protected void validateSid(short id)
- {
-
- // included only for interface compliance
- }
-
- protected void fillFields(byte [] data, short size)
- {
- field_1_charCount = LittleEndian.getShort(data, 0);
- field_2_optionflags = data[ 2 ];
- if ((field_2_optionflags & 1) == 0)
- {
- field_3_string = new String(data, 3, getCharCount());
- }
- else
- {
- char[] array = new char[ getCharCount() ];
-
- for (int j = 0; j < array.length; j++)
- {
- array[ j ] = ( char ) LittleEndian.getShort(data,
- 3 + (j * 2));
- }
- field_3_string = new String(array);
- }
- }
-
- /**
- * get the number of characters in the string
- *
- *
- * @return number of characters
- *
- */
-
- public short getCharCount()
- {
- return field_1_charCount;
- }
-
- /**
- * set the number of characters in the string
- * @param cc - number of characters
- */
-
- public void setCharCount(short cc)
- {
- field_1_charCount = cc;
- }
-
- /**
- * sets the number of characters to whaterver number of characters is in the
string
- * currently. effectively setCharCount(getString.length()).
- * @see #setString(String)
- * @see #getString()
- */
-
- public void setCharCount()
- {
- field_1_charCount = ( short ) field_3_string.length();
- }
-
- /**
- * get the option flags which among other things return if this is a 16-bit or
- * 8 bit string
- *
- * @return optionflags bitmask
- *
- */
-
- public byte getOptionFlags()
- {
- return field_2_optionflags;
- }
-
- /**
- * set the option flags which among other things return if this is a 16-bit or
- * 8 bit string
- *
- * @param of optionflags bitmask
- *
- */
-
- public void setOptionFlags(byte of)
- {
- field_2_optionflags = of;
- }
-
- /**
- * get the actual string this contains as a java String object
- *
- *
- * @return String
- *
- */
-
- public String getString()
- {
- return field_3_string;
- }
-
- /**
- * set the actual string this contains
- * @param string the text
- */
-
- public void setString(String string)
- {
- field_3_string = string;
- if (getCharCount() < field_3_string.length())
- {
- setCharCount();
- }
- }
-
- /**
- * unlike the real records we return the same as "getString()" rather than
debug info
- * @see #getDebugInfo()
- * @return String value of the record
- */
-
- public String toString()
- {
- return getString();
- }
-
- /**
- * return a character representation of the fields of this record
- *
- *
- * @return String of output for biffviewer etc.
- *
- */
-
- public String getDebugInfo()
- {
- StringBuffer buffer = new StringBuffer();
-
- buffer.append("[UNICODESTRING]\n");
- buffer.append(" .charcount = ")
- .append(Integer.toHexString(getCharCount())).append("\n");
- buffer.append(" .optionflags = ")
- .append(Integer.toHexString(getOptionFlags())).append("\n");
- buffer.append(" .string = ").append(getString())
- .append("\n");
- buffer.append("[/UNICODESTRING]\n");
- return buffer.toString();
- }
-
- public int serialize(int offset, byte [] data)
- {
- int charsize = 1;
-
- if (getOptionFlags() == 1)
- {
- charsize = 2;
- }
-
- // byte[] retval = new byte[ 3 + (getString().length() * charsize)];
- LittleEndian.putShort(data, 0 + offset, getCharCount());
- data[ 2 + offset ] = getOptionFlags();
-
-// System.out.println("Unicode: We've got "+retval[2]+" for our option
flag");
- try {
- String unicodeString = new
-String(getString().getBytes("Unicode"),"Unicode");
- if (getOptionFlags() == 0)
- {
- StringUtil.putCompressedUnicode(unicodeString, data, 0x3 +
-offset);
- }
- else
- {
- StringUtil.putUncompressedUnicode(unicodeString, data,
- 0x3 + offset);
- }
- }
- catch (Exception e) {
- if (getOptionFlags() == 0)
- {
- StringUtil.putCompressedUnicode(getString(), data, 0x3 +
- offset);
- }
- else
- {
- StringUtil.putUncompressedUnicode(getString(), data,
- 0x3 + offset);
- }
- }
- return getRecordSize();
- }
-
- private boolean isUncompressedUnicode()
- {
- return (getOptionFlags() & 0x01) == 1;
- }
-
- public int getRecordSize()
- {
- int charsize = isUncompressedUnicode() ? 2 : 1;
- return 3 + (getString().length() * charsize);
- }
-
- public short getSid()
- {
- return this.sid;
- }
-
- /**
- * called by the constructor, should set class level fields. Should throw
- * runtime exception for bad/icomplete data.
- *
- * @param data raw data
- * @param size size of data
- * @param offset of the records data (provided a big array of the file)
- */
-
- protected void fillFields(byte [] data, short size, int offset)
- {
- }
-
- public int compareTo(Object obj)
- {
- UnicodeString str = ( UnicodeString ) obj;
-
- return this.getString().compareTo(str.getString());
- }
-
- public boolean isRichText()
- {
- return (getOptionFlags() & RICH_TEXT_BIT) != 0;
- }
-
- int maxBrokenLength(final int proposedBrokenLength)
- {
- int rval = proposedBrokenLength;
-
- if (isUncompressedUnicode())
- {
- int proposedStringLength = proposedBrokenLength - 3;
-
- if ((proposedStringLength % 2) == 1)
- {
- proposedStringLength--;
- }
- rval = proposedStringLength + 3;
- }
- return rval;
- }
-
- public boolean isExtendedText()
- {
- return (getOptionFlags() & EXT_BIT) != 0;
- }
-
-}
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact [EMAIL PROTECTED]
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.poi.hssf.record;
+
+import java.io.UnsupportedEncodingException;
+
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * Title: Unicode String<P>
+ * Description: Unicode String record. We implement these as a record, although
+ * they are really just standard fields that are in several records.
+ * It is considered more desirable then repeating it in all of
them.<P>
+ * REFERENCE: PG 264 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver
+ * @author Marc Johnson (mjohnson at apache dot org)
+ * @author Glen Stampoultzis (glens at apache.org)
+ * @version 2.0-pre
+ */
+
+public class UnicodeString
+ extends Record
+ implements Comparable
+{
+ public final static short sid = 0xFFF;
+ private short field_1_charCount; // = 0;
+ private byte field_2_optionflags; // = 0;
+ private String field_3_string; // = null;
+ private final int RICH_TEXT_BIT = 8;
+ private final int EXT_BIT = 4;
+
+ public UnicodeString()
+ {
+ }
+
+
+ public int hashCode()
+ {
+ int stringHash = 0;
+ if (field_3_string != null)
+ stringHash = field_3_string.hashCode();
+ return field_1_charCount + stringHash;
+ }
+
+ /**
+ * Our handling of equals is inconsistent with compareTo. The trouble is
because we don't truely understand
+ * rich text fields yet it's difficult to make a sound comparison.
+ *
+ * @param o The object to compare.
+ * @return true if the object is actually equal.
+ */
+ public boolean equals(Object o)
+ {
+ if ((o == null) || (o.getClass() != this.getClass()))
+ {
+ return false;
+ }
+ UnicodeString other = ( UnicodeString ) o;
+
+ return ((field_1_charCount == other.field_1_charCount)
+ && (field_2_optionflags == other.field_2_optionflags)
+ && field_3_string.equals(other.field_3_string));
+ }
+
+ /**
+ * construct a unicode string record and fill its fields, ID is ignored
+ * @param id - ignored
+ * @param size - size of the data
+ * @param data - the bytes of the string/fields
+ */
+
+ public UnicodeString(short id, short size, byte [] data)
+ {
+ super(id, size, data);
+ }
+
+ /**
+ * construct a unicode string from a string fragment + data
+ */
+
+ public UnicodeString(short id, short size, byte [] data, String prefix)
+ {
+ this(id, size, data);
+ field_3_string = prefix + field_3_string;
+ setCharCount();
+ }
+
+ /**
+ * NO OP
+ */
+
+ protected void validateSid(short id)
+ {
+
+ // included only for interface compliance
+ }
+
+ protected void fillFields(byte [] data, short size)
+ {
+ field_1_charCount = LittleEndian.getShort(data, 0);
+ field_2_optionflags = data[ 2 ];
+ if ((field_2_optionflags & 1) == 0)
+ {
+ try {
+ field_3_string = new String(data, 3, getCharCount(),
+ StringUtil.getPreferredEncoding());
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ else
+ {
+ char[] array = new char[ getCharCount() ];
+
+ for (int j = 0; j < array.length; j++)
+ {
+ array[ j ] = ( char ) LittleEndian.getShort(data,
+ 3 + (j * 2));
+ }
+ field_3_string = new String(array);
+ }
+ }
+
+ /**
+ * get the number of characters in the string
+ *
+ *
+ * @return number of characters
+ *
+ */
+
+ public short getCharCount()
+ {
+ return field_1_charCount;
+ }
+
+ /**
+ * set the number of characters in the string
+ * @param cc - number of characters
+ */
+
+ public void setCharCount(short cc)
+ {
+ field_1_charCount = cc;
+ }
+
+ /**
+ * sets the number of characters to whaterver number of characters is in the
string
+ * currently. effectively setCharCount(getString.length()).
+ * @see #setString(String)
+ * @see #getString()
+ */
+
+ public void setCharCount()
+ {
+ field_1_charCount = ( short ) field_3_string.length();
+ }
+
+ /**
+ * get the option flags which among other things return if this is a 16-bit or
+ * 8 bit string
+ *
+ * @return optionflags bitmask
+ *
+ */
+
+ public byte getOptionFlags()
+ {
+ return field_2_optionflags;
+ }
+
+ /**
+ * set the option flags which among other things return if this is a 16-bit or
+ * 8 bit string
+ *
+ * @param of optionflags bitmask
+ *
+ */
+
+ public void setOptionFlags(byte of)
+ {
+ field_2_optionflags = of;
+ }
+
+ /**
+ * get the actual string this contains as a java String object
+ *
+ *
+ * @return String
+ *
+ */
+
+ public String getString()
+ {
+ return field_3_string;
+ }
+
+ /**
+ * set the actual string this contains
+ * @param string the text
+ */
+
+ public void setString(String string)
+ {
+ field_3_string = string;
+ if (getCharCount() < field_3_string.length())
+ {
+ setCharCount();
+ }
+ }
+
+ /**
+ * unlike the real records we return the same as "getString()" rather than
debug info
+ * @see #getDebugInfo()
+ * @return String value of the record
+ */
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ /**
+ * return a character representation of the fields of this record
+ *
+ *
+ * @return String of output for biffviewer etc.
+ *
+ */
+
+ public String getDebugInfo()
+ {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append("[UNICODESTRING]\n");
+ buffer.append(" .charcount = ")
+ .append(Integer.toHexString(getCharCount())).append("\n");
+ buffer.append(" .optionflags = ")
+ .append(Integer.toHexString(getOptionFlags())).append("\n");
+ buffer.append(" .string = ").append(getString())
+ .append("\n");
+ buffer.append("[/UNICODESTRING]\n");
+ return buffer.toString();
+ }
+
+ public int serialize(int offset, byte [] data)
+ {
+ int charsize = 1;
+
+ if (getOptionFlags() == 1)
+ {
+ charsize = 2;
+ }
+
+ // byte[] retval = new byte[ 3 + (getString().length() * charsize)];
+ LittleEndian.putShort(data, 0 + offset, getCharCount());
+ data[ 2 + offset ] = getOptionFlags();
+
+// System.out.println("Unicode: We've got "+retval[2]+" for our option
flag");
+ try {
+ String unicodeString = new
+String(getString().getBytes("Unicode"),"Unicode");
+ if (getOptionFlags() == 0)
+ {
+ StringUtil.putCompressedUnicode(unicodeString, data, 0x3 +
+offset);
+ }
+ else
+ {
+ StringUtil.putUncompressedUnicode(unicodeString, data,
+ 0x3 + offset);
+ }
+ }
+ catch (Exception e) {
+ if (getOptionFlags() == 0)
+ {
+ StringUtil.putCompressedUnicode(getString(), data, 0x3 +
+ offset);
+ }
+ else
+ {
+ StringUtil.putUncompressedUnicode(getString(), data,
+ 0x3 + offset);
+ }
+ }
+ return getRecordSize();
+ }
+
+ private boolean isUncompressedUnicode()
+ {
+ return (getOptionFlags() & 0x01) == 1;
+ }
+
+ public int getRecordSize()
+ {
+ int charsize = isUncompressedUnicode() ? 2 : 1;
+ return 3 + (getString().length() * charsize);
+ }
+
+ public short getSid()
+ {
+ return this.sid;
+ }
+
+ /**
+ * called by the constructor, should set class level fields. Should throw
+ * runtime exception for bad/icomplete data.
+ *
+ * @param data raw data
+ * @param size size of data
+ * @param offset of the records data (provided a big array of the file)
+ */
+
+ protected void fillFields(byte [] data, short size, int offset)
+ {
+ }
+
+ public int compareTo(Object obj)
+ {
+ UnicodeString str = ( UnicodeString ) obj;
+
+ return this.getString().compareTo(str.getString());
+ }
+
+ public boolean isRichText()
+ {
+ return (getOptionFlags() & RICH_TEXT_BIT) != 0;
+ }
+
+ int maxBrokenLength(final int proposedBrokenLength)
+ {
+ int rval = proposedBrokenLength;
+
+ if (isUncompressedUnicode())
+ {
+ int proposedStringLength = proposedBrokenLength - 3;
+
+ if ((proposedStringLength % 2) == 1)
+ {
+ proposedStringLength--;
+ }
+ rval = proposedStringLength + 3;
+ }
+ return rval;
+ }
+
+ public boolean isExtendedText()
+ {
+ return (getOptionFlags() & EXT_BIT) != 0;
+ }
+
+}
1.4 +222 -222 jakarta-poi/src/java/org/apache/poi/util/HexRead.java
Index: HexRead.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/util/HexRead.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- HexRead.java 12 Jun 2002 08:18:06 -0000 1.3
+++ HexRead.java 8 Nov 2002 02:34:08 -0000 1.4
@@ -1,222 +1,222 @@
-/* ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2002 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Apache" and "Apache Software Foundation" and
- * "Apache POI" must not be used to endorse or promote products
- * derived from this software without prior written permission. For
- * written permission, please contact [EMAIL PROTECTED]
- *
- * 5. Products derived from this software may not be called "Apache",
- * "Apache POI", nor may "Apache" appear in their name, without
- * prior written permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.poi.util;
-
-import java.io.IOException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * Utilities to read hex from files.
- *
- * @author Marc Johnson
- * @author Glen Stampoultzis (glens at apache.org)
- */
-public class HexRead
-{
- /**
- * This method reads hex data from a filename and returns a byte array.
- * The file may contain line comments that are preceeded with a # symbol.
- *
- * @param filename The filename to read
- * @return The bytes read from the file.
- * @throws IOException If there was a problem while reading the file.
- */
- public static byte[] readData( String filename )
- throws IOException
- {
- File file = new File( filename );
- FileInputStream stream = new FileInputStream( file );
- try
- {
- return readData(stream, -1);
- }
- finally
- {
- stream.close();
- }
- }
-
- /**
- * Same as readData(String) except that this method allows you to specify
sections within
- * a file. Sections are referenced using section headers in the form:
- * <pre>
- * [sectioname]
- * </pre>
- *
- * @see #readData(String)
- */
- public static byte[] readData(String filename, String section)
- throws IOException
- {
- File file = new File( filename );
- FileInputStream stream = new FileInputStream( file );
- try
- {
- StringBuffer sectionText = new StringBuffer();
- boolean inSection = false;
- int c = stream.read();
- while (c != -1)
- {
- switch(c)
- {
- case '[':
- inSection = true;
- break;
- case '\n': case '\r':
- inSection = false;
- sectionText = new StringBuffer();
- break;
- case ']':
- inSection = false;
- if (sectionText.toString().equals(section))
- return readData(stream, '[');
- sectionText = new StringBuffer();
- break;
- default:
- if (inSection)
- sectionText.append((char)c);
- }
-
- c = stream.read();
- }
- }
- finally
- {
- stream.close();
- }
- throw new IOException("Section '" + section + "' not found");
- }
-
- static private byte[] readData( FileInputStream stream, int eofChar ) throws
IOException
- {
- int characterCount = 0;
- byte b = (byte) 0;
- List bytes = new ArrayList();
- boolean done = false;
-
- while ( !done )
- {
- int count = stream.read();
- char baseChar = 'a';
-
- if ( count == eofChar)
- break;
-
- switch ( count )
- {
-
- case '#':
- readToEOL(stream);
- break;
- case '0': case '1': case '2': case '3': case '4': case '5': case
'6': case '7': case '8': case '9':
- b <<= 4;
- b += (byte) ( count - '0' );
- characterCount++;
- if ( characterCount == 2 )
- {
- bytes.add( new Byte( b ) );
- characterCount = 0;
- b = (byte) 0;
- }
- break;
-
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- baseChar = 'A';
-
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- b <<= 4;
- b += (byte) ( count + 10 - baseChar );
- characterCount++;
- if ( characterCount == 2 )
- {
- bytes.add( new Byte( b ) );
- characterCount = 0;
- b = (byte) 0;
- }
- break;
-
- case -1:
- done = true;
- break;
-
- default :
- break;
- }
- }
- Byte[] polished = (Byte[]) bytes.toArray( new Byte[0] );
- byte[] rval = new byte[polished.length];
-
- for ( int j = 0; j < polished.length; j++ )
- {
- rval[j] = polished[j].byteValue();
- }
- return rval;
- }
-
- static private void readToEOL( InputStream stream ) throws IOException
- {
- int c = stream.read();
- while ( c != -1 && c != '\n' && c != '\r')
- {
- c = stream.read();
- }
- }
-
-
-}
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact [EMAIL PROTECTED]
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.poi.util;
+
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Utilities to read hex from files.
+ *
+ * @author Marc Johnson
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public class HexRead
+{
+ /**
+ * This method reads hex data from a filename and returns a byte array.
+ * The file may contain line comments that are preceeded with a # symbol.
+ *
+ * @param filename The filename to read
+ * @return The bytes read from the file.
+ * @throws IOException If there was a problem while reading the file.
+ */
+ public static byte[] readData( String filename )
+ throws IOException
+ {
+ File file = new File( filename );
+ FileInputStream stream = new FileInputStream( file );
+ try
+ {
+ return readData(stream, -1);
+ }
+ finally
+ {
+ stream.close();
+ }
+ }
+
+ /**
+ * Same as readData(String) except that this method allows you to specify
sections within
+ * a file. Sections are referenced using section headers in the form:
+ * <pre>
+ * [sectioname]
+ * </pre>
+ *
+ * @see #readData(String)
+ */
+ public static byte[] readData(String filename, String section)
+ throws IOException
+ {
+ File file = new File( filename );
+ FileInputStream stream = new FileInputStream( file );
+ try
+ {
+ StringBuffer sectionText = new StringBuffer();
+ boolean inSection = false;
+ int c = stream.read();
+ while (c != -1)
+ {
+ switch(c)
+ {
+ case '[':
+ inSection = true;
+ break;
+ case '\n': case '\r':
+ inSection = false;
+ sectionText = new StringBuffer();
+ break;
+ case ']':
+ inSection = false;
+ if (sectionText.toString().equals(section))
+ return readData(stream, '[');
+ sectionText = new StringBuffer();
+ break;
+ default:
+ if (inSection)
+ sectionText.append((char)c);
+ }
+
+ c = stream.read();
+ }
+ }
+ finally
+ {
+ stream.close();
+ }
+ throw new IOException("Section '" + section + "' not found");
+ }
+
+ static private byte[] readData( FileInputStream stream, int eofChar ) throws
IOException
+ {
+ int characterCount = 0;
+ byte b = (byte) 0;
+ List bytes = new ArrayList();
+ boolean done = false;
+
+ while ( !done )
+ {
+ int count = stream.read();
+ char baseChar = 'a';
+
+ if ( count == eofChar)
+ break;
+
+ switch ( count )
+ {
+
+ case '#':
+ readToEOL(stream);
+ break;
+ case '0': case '1': case '2': case '3': case '4': case '5': case
'6': case '7': case '8': case '9':
+ b <<= 4;
+ b += (byte) ( count - '0' );
+ characterCount++;
+ if ( characterCount == 2 )
+ {
+ bytes.add( new Byte( b ) );
+ characterCount = 0;
+ b = (byte) 0;
+ }
+ break;
+
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ baseChar = 'A';
+
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ b <<= 4;
+ b += (byte) ( count + 10 - baseChar );
+ characterCount++;
+ if ( characterCount == 2 )
+ {
+ bytes.add( new Byte( b ) );
+ characterCount = 0;
+ b = (byte) 0;
+ }
+ break;
+
+ case -1:
+ done = true;
+ break;
+
+ default :
+ break;
+ }
+ }
+ Byte[] polished = (Byte[]) bytes.toArray( new Byte[0] );
+ byte[] rval = new byte[polished.length];
+
+ for ( int j = 0; j < polished.length; j++ )
+ {
+ rval[j] = polished[j].byteValue();
+ }
+ return rval;
+ }
+
+ static private void readToEOL( InputStream stream ) throws IOException
+ {
+ int c = stream.read();
+ while ( c != -1 && c != '\n' && c != '\r')
+ {
+ c = stream.read();
+ }
+ }
+
+
+}
1.7 +341 -334 jakarta-poi/src/java/org/apache/poi/util/StringUtil.java
Index: StringUtil.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/util/StringUtil.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- StringUtil.java 12 Sep 2002 01:49:40 -0000 1.6
+++ StringUtil.java 8 Nov 2002 02:34:08 -0000 1.7
@@ -1,334 +1,341 @@
-
-/*
- * ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2002 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Apache" and "Apache Software Foundation" and
- * "Apache POI" must not be used to endorse or promote products
- * derived from this software without prior written permission. For
- * written permission, please contact [EMAIL PROTECTED]
- *
- * 5. Products derived from this software may not be called "Apache",
- * "Apache POI", nor may "Apache" appear in their name, without
- * prior written permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.poi.util;
-
-import java.io.UnsupportedEncodingException;
-
-import java.text.NumberFormat;
-import java.text.FieldPosition;
-
-/**
- * Title: String Utility Description: Collection of string handling utilities
- *
- * Now it is quite confusing: the method pairs, in which
- * one of them write data and other read written data are:
- * putUncompressedUnicodeHigh and getFromUnicode
- * putUncompressedUnicode and getFromUnicodeHigh
- *
- *@author Andrew C. Oliver
- *@author Sergei Kozello (sergeikozello at mail.ru)
- *@created May 10, 2002
- *@version 1.0
- */
-
-public class StringUtil {
- /**
- * Constructor for the StringUtil object
- */
- private StringUtil() { }
-
-
- /**
- * given a byte array of 16-bit unicode characters, compress to 8-bit and
- * return a string
- *
- * { 0x16, 0x00 } -> 0x16
- *
- *@param string the byte array to be converted
- *@param offset the initial offset into the
- * byte array. it is assumed that string[ offset ] and string[ offset +
- * 1 ] contain the first 16-bit unicode character
- *@param len
- *@return the converted string
- *@exception ArrayIndexOutOfBoundsException if offset is out of bounds for
- * the byte array (i.e., is negative or is greater than or equal to
- * string.length)
- *@exception IllegalArgumentException if len is too large (i.e.,
- * there is not enough data in string to create a String of that
- * length)
- *@len the length of the final string
- */
-
- public static String getFromUnicodeHigh(final byte[] string,
- final int offset, final int len)
- throws ArrayIndexOutOfBoundsException, IllegalArgumentException {
- if ((offset < 0) || (offset >= string.length)) {
- throw new ArrayIndexOutOfBoundsException("Illegal offset");
- }
- if ((len < 0) || (((string.length - offset) / 2) < len)) {
- throw new IllegalArgumentException("Illegal length");
- }
-
- char[] chars = new char[ len ];
- for ( int i = 0; i < chars.length; i++ ) {
- chars[i] = (char)( string[ offset + ( 2*i ) ] & 0xFF |
- ( string[ offset + ( 2*i+1 ) ] << 8 ) );
- }
-
- return new String( chars );
- }
-
-
- /**
- * given a byte array of 16-bit unicode characters, compress to 8-bit and
- * return a string
- *
- * { 0x16, 0x00 } -> 0x16
- *
- *@param string the byte array to be converted
- *@return the converted string
- */
-
- public static String getFromUnicodeHigh( final byte[] string ) {
- return getFromUnicodeHigh( string, 0, string.length / 2 );
- }
-
-
- /**
- * given a byte array of 16-bit unicode characters, compress to 8-bit and
- * return a string
- *
- * { 0x00, 0x16 } -> 0x16
- *
- *@param string the byte array to be converted
- *@param offset the initial offset into the
- * byte array. it is assumed that string[ offset ] and string[ offset +
- * 1 ] contain the first 16-bit unicode character
- *@param len
- *@return the converted string
- *@exception ArrayIndexOutOfBoundsException if offset is out of bounds for
- * the byte array (i.e., is negative or is greater than or equal to
- * string.length)
- *@exception IllegalArgumentException if len is too large (i.e.,
- * there is not enough data in string to create a String of that
- * length)
- *@len the length of the final string
- */
-
- public static String getFromUnicode(final byte[] string,
- final int offset, final int len)
- throws ArrayIndexOutOfBoundsException, IllegalArgumentException {
- if ((offset < 0) || (offset >= string.length)) {
- throw new ArrayIndexOutOfBoundsException("Illegal offset");
- }
- if ((len < 0) || (((string.length - offset) / 2) < len)) {
- throw new IllegalArgumentException("Illegal length");
- }
-
-
- char[] chars = new char[ len ];
- for ( int i = 0; i < chars.length; i++ ) {
- chars[i] = (char)( ( string[ offset + ( 2*i ) ] << 8 ) +
- string[ offset + ( 2*i+1 ) ] );
- }
-
- return new String( chars );
- }
-
-
- /**
- * given a byte array of 16-bit unicode characters, compress to 8-bit and
- * return a string
- *
- * { 0x00, 0x16 } -> 0x16
- *
- *@param string the byte array to be converted
- *@return the converted string
- */
-
- public static String getFromUnicode(final byte[] string) {
- return getFromUnicode(string, 0, string.length / 2);
- }
-
-
- /**
- * write compressed unicode
- *
- *@param input the String containing the data to be written
- *@param output the byte array to which the data is to be written
- *@param offset an offset into the byte arrat at which the data is start
- * when written
- */
-
- public static void putCompressedUnicode(final String input,
- final byte[] output,
- final int offset) {
- int strlen = input.length();
-
- for (int k = 0; k < strlen; k++) {
- output[offset + k] = (byte) input.charAt(k);
- }
- }
-
-
- /**
- * Write uncompressed unicode
- *
- *@param input the String containing the unicode data to be written
- *@param output the byte array to hold the uncompressed unicode
- *@param offset the offset to start writing into the byte array
- */
-
- public static void putUncompressedUnicode(final String input,
- final byte[] output,
- final int offset) {
- int strlen = input.length();
-
- for (int k = 0; k < strlen; k++) {
- char c = input.charAt(k);
-
- output[offset + (2 * k)] = (byte) c;
- output[offset + (2 * k) + 1] = (byte) (c >> 8);
- }
- }
-
- /**
- * Write uncompressed unicode
- *
- *@param input the String containing the unicode data to be written
- *@param output the byte array to hold the uncompressed unicode
- *@param offset the offset to start writing into the byte array
- */
-
- public static void putUncompressedUnicodeHigh(final String input,
- final byte[] output,
- final int offset) {
- int strlen = input.length();
-
- for (int k = 0; k < strlen; k++) {
- char c = input.charAt(k);
-
- output[offset + (2 * k)] = (byte) (c >> 8);
- output[offset + (2 * k)] = (byte) c;
- }
- }
-
-
-
-
- /**
- * Description of the Method
- *
- *@param message Description of the Parameter
- *@param params Description of the Parameter
- *@return Description of the Return Value
- */
- public static String format(String message, Object[] params) {
- int currentParamNumber = 0;
- StringBuffer formattedMessage = new StringBuffer();
-
- for (int i = 0; i < message.length(); i++) {
- if (message.charAt(i) == '%') {
- if (currentParamNumber >= params.length) {
- formattedMessage.append("?missing data?");
- } else if ((params[currentParamNumber] instanceof Number)
- && (i + 1 < message.length())) {
- i += matchOptionalFormatting(
- (Number) params[currentParamNumber++],
- message.substring(i + 1), formattedMessage);
- } else {
-
formattedMessage.append(params[currentParamNumber++].toString());
- }
- } else {
- if ((message.charAt(i) == '\\') && (i + 1 < message.length())
- && (message.charAt(i + 1) == '%')) {
- formattedMessage.append('%');
- i++;
- } else {
- formattedMessage.append(message.charAt(i));
- }
- }
- }
- return formattedMessage.toString();
- }
-
-
- /**
- * Description of the Method
- *
- *@param number Description of the Parameter
- *@param formatting Description of the Parameter
- *@param outputTo Description of the Parameter
- *@return Description of the Return Value
- */
- private static int matchOptionalFormatting(Number number,
- String formatting,
- StringBuffer outputTo) {
- NumberFormat numberFormat = NumberFormat.getInstance();
-
- if ((0 < formatting.length())
- && Character.isDigit(formatting.charAt(0))) {
-
numberFormat.setMinimumIntegerDigits(Integer.parseInt(formatting.charAt(0) + ""));
- if ((2 < formatting.length()) && (formatting.charAt(1) == '.')
- && Character.isDigit(formatting.charAt(2))) {
-
numberFormat.setMaximumFractionDigits(Integer.parseInt(formatting.charAt(2) + ""));
- numberFormat.format(number, outputTo, new FieldPosition(0));
- return 3;
- }
- numberFormat.format(number, outputTo, new FieldPosition(0));
- return 1;
- } else if ((0 < formatting.length()) && (formatting.charAt(0) == '.')) {
- if ((1 < formatting.length())
- && Character.isDigit(formatting.charAt(1))) {
-
numberFormat.setMaximumFractionDigits(Integer.parseInt(formatting.charAt(1) + ""));
- numberFormat.format(number, outputTo, new FieldPosition(0));
- return 2;
- }
- }
- numberFormat.format(number, outputTo, new FieldPosition(0));
- return 1;
- }
-}
+
+/*
+ * ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact [EMAIL PROTECTED]
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.apache.poi.util;
+
+import java.io.UnsupportedEncodingException;
+
+import java.text.NumberFormat;
+import java.text.FieldPosition;
+
+/**
+ * Title: String Utility Description: Collection of string handling utilities
+ *
+ * Now it is quite confusing: the method pairs, in which
+ * one of them write data and other read written data are:
+ * putUncompressedUnicodeHigh and getFromUnicode
+ * putUncompressedUnicode and getFromUnicodeHigh
+ *
+ *@author Andrew C. Oliver
+ *@author Sergei Kozello (sergeikozello at mail.ru)
+ *@created May 10, 2002
+ *@version 1.0
+ */
+
+public class StringUtil {
+
+ private final static String ENCODING="ISO-8859-1";
+ /**
+ * Constructor for the StringUtil object
+ */
+ private StringUtil() { }
+
+
+ /**
+ * given a byte array of 16-bit unicode characters, compress to 8-bit and
+ * return a string
+ *
+ * { 0x16, 0x00 } -> 0x16
+ *
+ *@param string the byte array to be converted
+ *@param offset the initial offset into the
+ * byte array. it is assumed that string[ offset ] and string[ offset +
+ * 1 ] contain the first 16-bit unicode character
+ *@param len
+ *@return the converted string
+ *@exception ArrayIndexOutOfBoundsException if offset is out of bounds for
+ * the byte array (i.e., is negative or is greater than or equal to
+ * string.length)
+ *@exception IllegalArgumentException if len is too large (i.e.,
+ * there is not enough data in string to create a String of that
+ * length)
+ *@len the length of the final string
+ */
+
+ public static String getFromUnicodeHigh(final byte[] string,
+ final int offset, final int len)
+ throws ArrayIndexOutOfBoundsException, IllegalArgumentException {
+
+ if ((offset < 0) || (offset >= string.length)) {
+ throw new ArrayIndexOutOfBoundsException("Illegal offset");
+ }
+ if ((len < 0) || (((string.length - offset) / 2) < len)) {
+ throw new IllegalArgumentException("Illegal length");
+ }
+
+ char[] chars = new char[ len ];
+ for ( int i = 0; i < chars.length; i++ ) {
+ chars[i] = (char)( string[ offset + ( 2*i ) ] & 0xFF |
+ ( string[ offset + ( 2*i+1 ) ] << 8 ) );
+ }
+
+ return new String( chars );
+ }
+
+
+ /**
+ * given a byte array of 16-bit unicode characters, compress to 8-bit and
+ * return a string
+ *
+ * { 0x16, 0x00 } -> 0x16
+ *
+ *@param string the byte array to be converted
+ *@return the converted string
+ */
+
+ public static String getFromUnicodeHigh( final byte[] string ) {
+ return getFromUnicodeHigh( string, 0, string.length / 2 );
+ }
+
+
+ /**
+ * given a byte array of 16-bit unicode characters, compress to 8-bit and
+ * return a string
+ *
+ * { 0x00, 0x16 } -> 0x16
+ *
+ *@param string the byte array to be converted
+ *@param offset the initial offset into the
+ * byte array. it is assumed that string[ offset ] and string[ offset +
+ * 1 ] contain the first 16-bit unicode character
+ *@param len
+ *@return the converted string
+ *@exception ArrayIndexOutOfBoundsException if offset is out of bounds for
+ * the byte array (i.e., is negative or is greater than or equal to
+ * string.length)
+ *@exception IllegalArgumentException if len is too large (i.e.,
+ * there is not enough data in string to create a String of that
+ * length)
+ *@len the length of the final string
+ */
+
+ public static String getFromUnicode(final byte[] string,
+ final int offset, final int len)
+ throws ArrayIndexOutOfBoundsException, IllegalArgumentException {
+ if ((offset < 0) || (offset >= string.length)) {
+ throw new ArrayIndexOutOfBoundsException("Illegal offset");
+ }
+ if ((len < 0) || (((string.length - offset) / 2) < len)) {
+ throw new IllegalArgumentException("Illegal length");
+ }
+
+
+ char[] chars = new char[ len ];
+ for ( int i = 0; i < chars.length; i++ ) {
+ chars[i] = (char)( ( string[ offset + ( 2*i ) ] << 8 ) +
+ string[ offset + ( 2*i+1 ) ] );
+ }
+
+ return new String( chars );
+ }
+
+
+ /**
+ * given a byte array of 16-bit unicode characters, compress to 8-bit and
+ * return a string
+ *
+ * { 0x00, 0x16 } -> 0x16
+ *
+ *@param string the byte array to be converted
+ *@return the converted string
+ */
+
+ public static String getFromUnicode(final byte[] string) {
+ return getFromUnicode(string, 0, string.length / 2);
+ }
+
+
+ /**
+ * write compressed unicode
+ *
+ *@param input the String containing the data to be written
+ *@param output the byte array to which the data is to be written
+ *@param offset an offset into the byte arrat at which the data is start
+ * when written
+ */
+
+ public static void putCompressedUnicode(final String input,
+ final byte[] output,
+ final int offset) {
+ int strlen = input.length();
+
+ for (int k = 0; k < strlen; k++) {
+ output[offset + k] = (byte) input.charAt(k);
+ }
+ }
+
+
+ /**
+ * Write uncompressed unicode
+ *
+ *@param input the String containing the unicode data to be written
+ *@param output the byte array to hold the uncompressed unicode
+ *@param offset the offset to start writing into the byte array
+ */
+
+ public static void putUncompressedUnicode(final String input,
+ final byte[] output,
+ final int offset) {
+ int strlen = input.length();
+
+ for (int k = 0; k < strlen; k++) {
+ char c = input.charAt(k);
+
+ output[offset + (2 * k)] = (byte) c;
+ output[offset + (2 * k) + 1] = (byte) (c >> 8);
+ }
+ }
+
+ /**
+ * Write uncompressed unicode
+ *
+ *@param input the String containing the unicode data to be written
+ *@param output the byte array to hold the uncompressed unicode
+ *@param offset the offset to start writing into the byte array
+ */
+
+ public static void putUncompressedUnicodeHigh(final String input,
+ final byte[] output,
+ final int offset) {
+ int strlen = input.length();
+
+ for (int k = 0; k < strlen; k++) {
+ char c = input.charAt(k);
+
+ output[offset + (2 * k)] = (byte) (c >> 8);
+ output[offset + (2 * k)] = (byte) c;
+ }
+ }
+
+
+
+
+ /**
+ * Description of the Method
+ *
+ *@param message Description of the Parameter
+ *@param params Description of the Parameter
+ *@return Description of the Return Value
+ */
+ public static String format(String message, Object[] params) {
+ int currentParamNumber = 0;
+ StringBuffer formattedMessage = new StringBuffer();
+
+ for (int i = 0; i < message.length(); i++) {
+ if (message.charAt(i) == '%') {
+ if (currentParamNumber >= params.length) {
+ formattedMessage.append("?missing data?");
+ } else if ((params[currentParamNumber] instanceof Number)
+ && (i + 1 < message.length())) {
+ i += matchOptionalFormatting(
+ (Number) params[currentParamNumber++],
+ message.substring(i + 1), formattedMessage);
+ } else {
+
formattedMessage.append(params[currentParamNumber++].toString());
+ }
+ } else {
+ if ((message.charAt(i) == '\\') && (i + 1 < message.length())
+ && (message.charAt(i + 1) == '%')) {
+ formattedMessage.append('%');
+ i++;
+ } else {
+ formattedMessage.append(message.charAt(i));
+ }
+ }
+ }
+ return formattedMessage.toString();
+ }
+
+
+ /**
+ * Description of the Method
+ *
+ *@param number Description of the Parameter
+ *@param formatting Description of the Parameter
+ *@param outputTo Description of the Parameter
+ *@return Description of the Return Value
+ */
+ private static int matchOptionalFormatting(Number number,
+ String formatting,
+ StringBuffer outputTo) {
+ NumberFormat numberFormat = NumberFormat.getInstance();
+
+ if ((0 < formatting.length())
+ && Character.isDigit(formatting.charAt(0))) {
+
numberFormat.setMinimumIntegerDigits(Integer.parseInt(formatting.charAt(0) + ""));
+ if ((2 < formatting.length()) && (formatting.charAt(1) == '.')
+ && Character.isDigit(formatting.charAt(2))) {
+
numberFormat.setMaximumFractionDigits(Integer.parseInt(formatting.charAt(2) + ""));
+ numberFormat.format(number, outputTo, new FieldPosition(0));
+ return 3;
+ }
+ numberFormat.format(number, outputTo, new FieldPosition(0));
+ return 1;
+ } else if ((0 < formatting.length()) && (formatting.charAt(0) == '.')) {
+ if ((1 < formatting.length())
+ && Character.isDigit(formatting.charAt(1))) {
+
numberFormat.setMaximumFractionDigits(Integer.parseInt(formatting.charAt(1) + ""));
+ numberFormat.format(number, outputTo, new FieldPosition(0));
+ return 2;
+ }
+ }
+ numberFormat.format(number, outputTo, new FieldPosition(0));
+ return 1;
+ }
+
+ public static String getPreferredEncoding() {
+ return ENCODING;
+ }
+}
1.6 +366 -358
jakarta-poi/src/testcases/org/apache/poi/util/TestStringUtil.java
Index: TestStringUtil.java
===================================================================
RCS file:
/home/cvs/jakarta-poi/src/testcases/org/apache/poi/util/TestStringUtil.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- TestStringUtil.java 2 Sep 2002 02:11:16 -0000 1.5
+++ TestStringUtil.java 8 Nov 2002 02:34:08 -0000 1.6
@@ -1,358 +1,366 @@
-
-/* ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2002 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Apache" and "Apache Software Foundation" and
- * "Apache POI" must not be used to endorse or promote products
- * derived from this software without prior written permission. For
- * written permission, please contact [EMAIL PROTECTED]
- *
- * 5. Products derived from this software may not be called "Apache",
- * "Apache POI", nor may "Apache" appear in their name, without
- * prior written permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.poi.util;
-
-import junit.framework.*;
-
-import java.text.NumberFormat;
-
-/**
- * Unit test for StringUtil
- *
- * @author Marc Johnson (mjohnson at apache dot org
- * @author Glen Stampoultzis (glens at apache.org)
- * @author Sergei Kozello (sergeikozello at mail.ru)
- */
-
-public class TestStringUtil
- extends TestCase
-{
-
- /**
- * Creates new TestStringUtil
- *
- * @param name
- */
-
- public TestStringUtil(String name)
- {
- super(name);
- }
-
- /**
- * test simple form of getFromUnicode
- */
-
- public void testSimpleGetFromUnicode()
- {
- byte[] test_data = new byte[ 32 ];
- int index = 0;
-
- for (int k = 0; k < 16; k++)
- {
- test_data[ index++ ] = ( byte ) 0;
- test_data[ index++ ] = ( byte ) ('a' + k);
- }
- assertEquals("abcdefghijklmnop",
- StringUtil.getFromUnicode(test_data));
- }
-
- /**
- * test simple form of getFromUnicode with symbols with code below and more 127
- */
-
- public void testGetFromUnicodeSymbolsWithCodesMoreThan127()
- {
- byte[] test_data = new byte[] { 0x04, 0x22,
- 0x04, 0x35,
- 0x04, 0x41,
- 0x04, 0x42,
- 0x00, 0x20,
- 0x00, 0x74,
- 0x00, 0x65,
- 0x00, 0x73,
- 0x00, 0x74,
- };
-
- assertEquals("\u0422\u0435\u0441\u0442 test",
- StringUtil.getFromUnicode(test_data));
- }
-
- /**
- * test getFromUnicodeHigh for symbols with code below and more 127
- */
-
- public void testGetFromUnicodeHighSymbolsWithCodesMoreThan127()
- {
- byte[] test_data = new byte[] { 0x22, 0x04,
- 0x35, 0x04,
- 0x41, 0x04,
- 0x42, 0x04,
- 0x20, 0x00,
- 0x74, 0x00,
- 0x65, 0x00,
- 0x73, 0x00,
- 0x74, 0x00,
- };
-
- assertEquals("\u0422\u0435\u0441\u0442 test",
- StringUtil.getFromUnicodeHigh( test_data ) );
- }
-
- /**
- * Test more complex form of getFromUnicode
- */
-
- public void testComplexGetFromUnicode()
- {
- byte[] test_data = new byte[ 32 ];
- int index = 0;
-
- for (int k = 0; k < 16; k++)
- {
- test_data[ index++ ] = ( byte ) 0;
- test_data[ index++ ] = ( byte ) ('a' + k);
- }
- assertEquals("abcdefghijklmno",
- StringUtil.getFromUnicode(test_data, 0, 15));
- assertEquals("bcdefghijklmnop",
- StringUtil.getFromUnicode(test_data, 2, 15));
- try
- {
- StringUtil.getFromUnicode(test_data, -1, 16);
- fail("Should have caught ArrayIndexOutOfBoundsException");
- }
- catch (ArrayIndexOutOfBoundsException ignored)
- {
-
- // as expected
- }
- try
- {
- StringUtil.getFromUnicode(test_data, 32, 16);
- fail("Should have caught ArrayIndexOutOfBoundsException");
- }
- catch (ArrayIndexOutOfBoundsException ignored)
- {
-
- // as expected
- }
- try
- {
- StringUtil.getFromUnicode(test_data, 1, 16);
- fail("Should have caught IllegalArgumentException");
- }
- catch (IllegalArgumentException ignored)
- {
-
- // as expected
- }
- try
- {
- StringUtil.getFromUnicode(test_data, 1, -1);
- fail("Should have caught IllegalArgumentException");
- }
- catch (IllegalArgumentException ignored)
- {
-
- // as expected
- }
- }
-
- /**
- * Test putCompressedUnicode
- */
-
- public void testPutCompressedUnicode()
- {
- byte[] output = new byte[ 100 ];
- byte[] expected_output =
- {
- ( byte ) 'H', ( byte ) 'e', ( byte ) 'l', ( byte ) 'l',
- ( byte ) 'o', ( byte ) ' ', ( byte ) 'W', ( byte ) 'o',
- ( byte ) 'r', ( byte ) 'l', ( byte ) 'd', ( byte ) 0xAE
- };
- String input = new String(expected_output);
-
- StringUtil.putCompressedUnicode(input, output, 0);
- for (int j = 0; j < expected_output.length; j++)
- {
- assertEquals("testing offset " + j, expected_output[ j ],
- output[ j ]);
- }
- StringUtil.putCompressedUnicode(input, output,
- 100 - expected_output.length);
- for (int j = 0; j < expected_output.length; j++)
- {
- assertEquals("testing offset " + j, expected_output[ j ],
- output[ 100 + j - expected_output.length ]);
- }
- try
- {
- StringUtil.putCompressedUnicode(input, output,
- 101 - expected_output.length);
- fail("Should have caught ArrayIndexOutOfBoundsException");
- }
- catch (ArrayIndexOutOfBoundsException ignored)
- {
-
- // as expected
- }
- }
-
- /**
- * Test putUncompressedUnicode
- */
-
- public void testPutUncompressedUnicode()
- {
- byte[] output = new byte[ 100 ];
- String input = "Hello World";
- byte[] expected_output =
- {
- ( byte ) 'H', ( byte ) 0, ( byte ) 'e', ( byte ) 0, ( byte ) 'l',
- ( byte ) 0, ( byte ) 'l', ( byte ) 0, ( byte ) 'o', ( byte ) 0,
- ( byte ) ' ', ( byte ) 0, ( byte ) 'W', ( byte ) 0, ( byte ) 'o',
- ( byte ) 0, ( byte ) 'r', ( byte ) 0, ( byte ) 'l', ( byte ) 0,
- ( byte ) 'd', ( byte ) 0
- };
-
- StringUtil.putUncompressedUnicode(input, output, 0);
- for (int j = 0; j < expected_output.length; j++)
- {
- assertEquals("testing offset " + j, expected_output[ j ],
- output[ j ]);
- }
- StringUtil.putUncompressedUnicode(input, output,
- 100 - expected_output.length);
- for (int j = 0; j < expected_output.length; j++)
- {
- assertEquals("testing offset " + j, expected_output[ j ],
- output[ 100 + j - expected_output.length ]);
- }
- try
- {
- StringUtil.putUncompressedUnicode(input, output,
- 101 - expected_output.length);
- fail("Should have caught ArrayIndexOutOfBoundsException");
- }
- catch (ArrayIndexOutOfBoundsException ignored)
- {
-
- // as expected
- }
- }
-
- public void testFormat()
- throws Exception
- {
- assertEquals("This is a test " + fmt(1.2345, 2, 2),
- StringUtil.format("This is a test %2.2", new Object[]
- {
- new Double(1.2345)
- }));
- assertEquals("This is a test " + fmt(1.2345, -1, 3),
- StringUtil.format("This is a test %.3", new Object[]
- {
- new Double(1.2345)
- }));
- assertEquals("This is a great test " + fmt(1.2345, -1, 3),
- StringUtil.format("This is a % test %.3", new Object[]
- {
- "great", new Double(1.2345)
- }));
- assertEquals("This is a test 1",
- StringUtil.format("This is a test %", new Object[]
- {
- new Integer(1)
- }));
- assertEquals("This is a test 1",
- StringUtil.format("This is a test %", new Object[]
- {
- new Integer(1), new Integer(1)
- }));
- assertEquals("This is a test 1.x",
- StringUtil.format("This is a test %1.x", new Object[]
- {
- new Integer(1)
- }));
- assertEquals("This is a test ?missing data?1.x",
- StringUtil.format("This is a test %1.x", new Object[]
- {
- }));
- assertEquals("This is a test %1.x",
- StringUtil.format("This is a test \\%1.x", new Object[]
- {
- }));
- }
-
- private String fmt(double num, int minIntDigits, int maxFracDigitis)
- {
- NumberFormat nf = NumberFormat.getInstance();
-
- if (minIntDigits != -1)
- {
- nf.setMinimumIntegerDigits(minIntDigits);
- }
- if (maxFracDigitis != -1)
- {
- nf.setMaximumFractionDigits(maxFracDigitis);
- }
- return nf.format(num);
- }
-
- /**
- * main
- *
- * @param ignored_args
- */
-
- public static void main(String [] ignored_args)
- {
- System.out.println("Testing util.StringUtil functionality");
- junit.textui.TestRunner.run(TestStringUtil.class);
- }
-}
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact [EMAIL PROTECTED]
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.poi.util;
+
+import junit.framework.*;
+
+import java.text.NumberFormat;
+
+/**
+ * Unit test for StringUtil
+ *
+ * @author Marc Johnson (mjohnson at apache dot org
+ * @author Glen Stampoultzis (glens at apache.org)
+ * @author Sergei Kozello (sergeikozello at mail.ru)
+ */
+
+public class TestStringUtil
+ extends TestCase
+{
+
+ /**
+ * Creates new TestStringUtil
+ *
+ * @param name
+ */
+
+ public TestStringUtil(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * test simple form of getFromUnicode
+ */
+
+ public void testSimpleGetFromUnicode()
+ {
+ byte[] test_data = new byte[ 32 ];
+ int index = 0;
+
+ for (int k = 0; k < 16; k++)
+ {
+ test_data[ index++ ] = ( byte ) 0;
+ test_data[ index++ ] = ( byte ) ('a' + k);
+ }
+ assertEquals("abcdefghijklmnop",
+ StringUtil.getFromUnicode(test_data));
+ }
+
+ /**
+ * test simple form of getFromUnicode with symbols with code below and more 127
+ */
+
+ public void testGetFromUnicodeSymbolsWithCodesMoreThan127()
+ {
+ byte[] test_data = new byte[] { 0x04, 0x22,
+ 0x04, 0x35,
+ 0x04, 0x41,
+ 0x04, 0x42,
+ 0x00, 0x20,
+ 0x00, 0x74,
+ 0x00, 0x65,
+ 0x00, 0x73,
+ 0x00, 0x74,
+ };
+
+ assertEquals("\u0422\u0435\u0441\u0442 test",
+ StringUtil.getFromUnicode(test_data));
+ }
+
+ /**
+ * test getFromUnicodeHigh for symbols with code below and more 127
+ */
+
+ public void testGetFromUnicodeHighSymbolsWithCodesMoreThan127()
+ {
+ byte[] test_data = new byte[] { 0x22, 0x04,
+ 0x35, 0x04,
+ 0x41, 0x04,
+ 0x42, 0x04,
+ 0x20, 0x00,
+ 0x74, 0x00,
+ 0x65, 0x00,
+ 0x73, 0x00,
+ 0x74, 0x00,
+ };
+
+ assertEquals("\u0422\u0435\u0441\u0442 test",
+ StringUtil.getFromUnicodeHigh( test_data ) );
+ }
+
+ /**
+ * Test more complex form of getFromUnicode
+ */
+
+ public void testComplexGetFromUnicode()
+ {
+ byte[] test_data = new byte[ 32 ];
+ int index = 0;
+
+ for (int k = 0; k < 16; k++)
+ {
+ test_data[ index++ ] = ( byte ) 0;
+ test_data[ index++ ] = ( byte ) ('a' + k);
+ }
+ assertEquals("abcdefghijklmno",
+ StringUtil.getFromUnicode(test_data, 0, 15));
+ assertEquals("bcdefghijklmnop",
+ StringUtil.getFromUnicode(test_data, 2, 15));
+ try
+ {
+ StringUtil.getFromUnicode(test_data, -1, 16);
+ fail("Should have caught ArrayIndexOutOfBoundsException");
+ }
+ catch (ArrayIndexOutOfBoundsException ignored)
+ {
+
+ // as expected
+ }
+ try
+ {
+ StringUtil.getFromUnicode(test_data, 32, 16);
+ fail("Should have caught ArrayIndexOutOfBoundsException");
+ }
+ catch (ArrayIndexOutOfBoundsException ignored)
+ {
+
+ // as expected
+ }
+ try
+ {
+ StringUtil.getFromUnicode(test_data, 1, 16);
+ fail("Should have caught IllegalArgumentException");
+ }
+ catch (IllegalArgumentException ignored)
+ {
+
+ // as expected
+ }
+ try
+ {
+ StringUtil.getFromUnicode(test_data, 1, -1);
+ fail("Should have caught IllegalArgumentException");
+ }
+ catch (IllegalArgumentException ignored)
+ {
+
+ // as expected
+ }
+ }
+
+ /**
+ * Test putCompressedUnicode
+ */
+
+ public void testPutCompressedUnicode() throws Exception
+ {
+ byte[] output = new byte[ 100 ];
+ byte[] expected_output =
+ {
+ ( byte ) 'H', ( byte ) 'e', ( byte ) 'l', ( byte ) 'l',
+ ( byte ) 'o', ( byte ) ' ', ( byte ) 'W', ( byte ) 'o',
+ ( byte ) 'r', ( byte ) 'l', ( byte ) 'd', ( byte ) 0xAE
+ };
+ String input = new
String(expected_output,StringUtil.getPreferredEncoding());
+
+ StringUtil.putCompressedUnicode(input, output, 0);
+ for (int j = 0; j < expected_output.length; j++)
+ {
+ assertEquals("testing offset " + j, expected_output[ j ],
+ output[ j ]);
+ }
+ StringUtil.putCompressedUnicode(input, output,
+ 100 - expected_output.length);
+ for (int j = 0; j < expected_output.length; j++)
+ {
+ assertEquals("testing offset " + j, expected_output[ j ],
+ output[ 100 + j - expected_output.length ]);
+ }
+ try
+ {
+ StringUtil.putCompressedUnicode(input, output,
+ 101 - expected_output.length);
+ fail("Should have caught ArrayIndexOutOfBoundsException");
+ }
+ catch (ArrayIndexOutOfBoundsException ignored)
+ {
+
+ // as expected
+ }
+ }
+
+ /**
+ * Test putUncompressedUnicode
+ */
+
+ public void testPutUncompressedUnicode()
+ {
+ byte[] output = new byte[ 100 ];
+ String input = "Hello World";
+ byte[] expected_output =
+ {
+ ( byte ) 'H', ( byte ) 0, ( byte ) 'e', ( byte ) 0, ( byte ) 'l',
+ ( byte ) 0, ( byte ) 'l', ( byte ) 0, ( byte ) 'o', ( byte ) 0,
+ ( byte ) ' ', ( byte ) 0, ( byte ) 'W', ( byte ) 0, ( byte ) 'o',
+ ( byte ) 0, ( byte ) 'r', ( byte ) 0, ( byte ) 'l', ( byte ) 0,
+ ( byte ) 'd', ( byte ) 0
+ };
+
+ StringUtil.putUncompressedUnicode(input, output, 0);
+ for (int j = 0; j < expected_output.length; j++)
+ {
+ assertEquals("testing offset " + j, expected_output[ j ],
+ output[ j ]);
+ }
+ StringUtil.putUncompressedUnicode(input, output,
+ 100 - expected_output.length);
+ for (int j = 0; j < expected_output.length; j++)
+ {
+ assertEquals("testing offset " + j, expected_output[ j ],
+ output[ 100 + j - expected_output.length ]);
+ }
+ try
+ {
+ StringUtil.putUncompressedUnicode(input, output,
+ 101 - expected_output.length);
+ fail("Should have caught ArrayIndexOutOfBoundsException");
+ }
+ catch (ArrayIndexOutOfBoundsException ignored)
+ {
+
+ // as expected
+ }
+ }
+
+ public void testFormat()
+ throws Exception
+ {
+ assertEquals("This is a test " + fmt(1.2345, 2, 2),
+ StringUtil.format("This is a test %2.2", new Object[]
+ {
+ new Double(1.2345)
+ }));
+ assertEquals("This is a test " + fmt(1.2345, -1, 3),
+ StringUtil.format("This is a test %.3", new Object[]
+ {
+ new Double(1.2345)
+ }));
+ assertEquals("This is a great test " + fmt(1.2345, -1, 3),
+ StringUtil.format("This is a % test %.3", new Object[]
+ {
+ "great", new Double(1.2345)
+ }));
+ assertEquals("This is a test 1",
+ StringUtil.format("This is a test %", new Object[]
+ {
+ new Integer(1)
+ }));
+ assertEquals("This is a test 1",
+ StringUtil.format("This is a test %", new Object[]
+ {
+ new Integer(1), new Integer(1)
+ }));
+ assertEquals("This is a test 1.x",
+ StringUtil.format("This is a test %1.x", new Object[]
+ {
+ new Integer(1)
+ }));
+ assertEquals("This is a test ?missing data?1.x",
+ StringUtil.format("This is a test %1.x", new Object[]
+ {
+ }));
+ assertEquals("This is a test %1.x",
+ StringUtil.format("This is a test \\%1.x", new Object[]
+ {
+ }));
+ }
+
+ private String fmt(double num, int minIntDigits, int maxFracDigitis)
+ {
+ NumberFormat nf = NumberFormat.getInstance();
+
+ if (minIntDigits != -1)
+ {
+ nf.setMinimumIntegerDigits(minIntDigits);
+ }
+ if (maxFracDigitis != -1)
+ {
+ nf.setMaximumFractionDigits(maxFracDigitis);
+ }
+ return nf.format(num);
+ }
+
+ /**
+ * main
+ *
+ * @param ignored_args
+ */
+
+ public static void main(String [] ignored_args)
+ {
+ System.out.println("Testing util.StringUtil functionality");
+ junit.textui.TestRunner.run(TestStringUtil.class);
+ }
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ // System.setProperty()
+ }
+
+}
--
To unsubscribe, e-mail: <mailto:poi-dev-unsubscribe@;jakarta.apache.org>
For additional commands, e-mail: <mailto:poi-dev-help@;jakarta.apache.org>