📄 utility.java
字号:
/*Copyright (c) 2002-2005, Dennis M. Sosnoski.All rights reserved.Redistribution and use in source and binary forms, with or without modification,are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of JiBX nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ANDANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AREDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FORANY 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 ONANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/package org.jibx.runtime;import java.lang.reflect.Array;//#!j2me{import java.sql.Time;import java.sql.Timestamp;//#j2me}import java.util.ArrayList;import java.util.Calendar;import java.util.Date;import java.util.GregorianCalendar;import java.util.List;/** * Utility class supplying static methods. Date serialization is based on the * algorithms published by Peter Baum (http://www.capecod.net/~pbaum). All date * handling is done according to the W3C Schema specification, which uses a * proleptic Gregorian calendar with no year 0. Note that this differs from the * Java date handling, which uses a discontinuous Gregorian calendar. * * @author Dennis M. Sosnoski * @version 1.0 */public abstract class Utility{ /** Minimum size for array returned by {@link #growArray}. */ public static final int MINIMUM_GROWN_ARRAY_SIZE = 16; /** Number of milliseconds in a minute. */ private static final int MSPERMINUTE = 60000; /** Number of milliseconds in an hour. */ private static final int MSPERHOUR = MSPERMINUTE*60; /** Number of milliseconds in a day. */ private static final int MSPERDAY = MSPERHOUR*24; /** Number of milliseconds in a day as a long. */ private static final long LMSPERDAY = (long)MSPERDAY; /** Number of milliseconds in a (non-leap) year. */ private static final long MSPERYEAR = LMSPERDAY*365; /** Average number of milliseconds in a year within century. */ private static final long MSPERAVGYEAR = (long)(MSPERDAY*365.25); /** Number of milliseconds in a normal century. */ private static final long MSPERCENTURY = (long)(MSPERDAY*36524.25); /** Millisecond value of base time for internal representation. This gives the bias relative to January 1 of the year 1 C.E. */ private static final long TIME_BASE = 1969*MSPERYEAR + (1969/4 - 19 + 4)*LMSPERDAY; /** Day number for start of month in non-leap year. */ private static final int[] MONTHS_NONLEAP = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; /** Day number for start of month in non-leap year. */ private static final int[] MONTHS_LEAP = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }; /** Millisecond count prior to start of month in March 1-biased year. */ private static final long[] BIAS_MONTHMS = { 0*LMSPERDAY, 0*LMSPERDAY, 0*LMSPERDAY, 0*LMSPERDAY, 31*LMSPERDAY, 61*LMSPERDAY, 92*LMSPERDAY, 122*LMSPERDAY, 153*LMSPERDAY, 184*LMSPERDAY, 214*LMSPERDAY, 245*LMSPERDAY, 275*LMSPERDAY, 306*LMSPERDAY, 337*LMSPERDAY }; /** Date for setting change to Gregorian calendar. */ private static Date BEGINNING_OF_TIME = new Date(Long.MIN_VALUE); /** Pad character for base64 encoding. */ private static final char PAD_CHAR = '='; /** Characters used in base64 encoding. */ private static final char[] s_base64Chars = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; /** Values corresponding to characters used in bas64 encoding. */ private static final byte[] s_base64Values = new byte[128]; static { for (int i = 0; i < s_base64Values.length; i++) { s_base64Values[i] = -1; } s_base64Values[PAD_CHAR] = 0; for (int i = 0; i < s_base64Chars.length; i++) { s_base64Values[s_base64Chars[i]] = (byte)i; } } /** * Parse digits in text as integer value. This internal method is used * for number values embedded within lexical structures. Only decimal * digits can be included in the text range parsed. * * @param text text to be parsed * @param offset starting offset in text * @param length number of digits to be parsed * @return converted positive integer value * @throws JiBXException on parse error */ private static int parseDigits(String text, int offset, int length) throws JiBXException { // check if overflow a potential problem int value = 0; if (length > 9) { // use library parse code for potential overflow try { value = Integer.parseInt(text.substring(offset, offset+length)); } catch (NumberFormatException ex) { throw new JiBXException(ex.getMessage()); } } else { // parse with no overflow worries int limit = offset + length; while (offset < limit) { char chr = text.charAt(offset++); if (chr >= '0' && chr <= '9') { value = value * 10 + (chr - '0'); } else { throw new JiBXException("Non-digit in number value"); } } } return value; } /** * Parse integer value from text. Integer values are parsed with optional * leading sign flag, followed by any number of digits. * * @param text text to be parsed * @return converted integer value * @throws JiBXException on parse error */ public static int parseInt(String text) throws JiBXException { // make sure there's text to be processed text = text.trim(); int offset = 0; int limit = text.length(); if (limit == 0) { throw new JiBXException("Empty number value"); } // check leading sign present in text boolean negate = false; char chr = text.charAt(0); if (chr == '-') { if (limit > 9) { // special case to make sure maximum negative value handled try { return Integer.parseInt(text); } catch (NumberFormatException ex) { throw new JiBXException(ex.getMessage()); } } else { negate = true; offset++; } } else if (chr == '+') { offset++; } if (offset >= limit) { throw new JiBXException("Invalid number format"); } // handle actual value conversion int value = parseDigits(text, offset, limit-offset); if (negate) { return -value; } else { return value; } } /** * Serialize int value to text. * * @param value int value to be serialized * @return text representation of value */ public static String serializeInt(int value) { return Integer.toString(value); } /** * Parse long value from text. Long values are parsed with optional * leading sign flag, followed by any number of digits. * * @param text text to be parsed * @return converted long value * @throws JiBXException on parse error */ public static long parseLong(String text) throws JiBXException { // make sure there's text to be processed text = text.trim(); int offset = 0; int limit = text.length(); if (limit == 0) { throw new JiBXException("Empty number value"); } // check leading sign present in text boolean negate = false; char chr = text.charAt(0); if (chr == '-') { negate = true; offset++; } else if (chr == '+') { offset++; } if (offset >= limit) { throw new JiBXException("Invalid number format"); } // check if overflow a potential problem long value = 0; if (limit-offset > 18) { // pass text to library parse code (less leading +) if (chr == '+') { text = text.substring(1); } try { value = Long.parseLong(text); } catch (NumberFormatException ex) { throw new JiBXException(ex.getMessage()); } } else { // parse with no overflow worries while (offset < limit) { chr = text.charAt(offset++); if (chr >= '0' && chr <= '9') { value = value * 10 + (chr - '0'); } else { throw new JiBXException("Non-digit in number value"); } } if (negate) { value = -value; } } return value; } /** * Serialize long value to text. * * @param value long value to be serialized * @return text representation of value */ public static String serializeLong(long value) { return Long.toString(value); } /** * Convert gYear text to Java date. Date values are expected to be in * W3C XML Schema standard format as CCYY, with optional leading sign. * * @param text text to be parsed * @return start of year date as millisecond value from 1 C.E. * @throws JiBXException on parse error */ public static long parseYear(String text) throws JiBXException { // start by validating the length text = text.trim(); boolean valid = true; int minc = 4; char chr = text.charAt(0); if (chr == '-') { minc = 5; } else if (chr == '+') { valid = false; } if (text.length() < minc) { valid = false; } if (!valid) { throw new JiBXException("Invalid year format"); } // handle year conversion int year = parseInt(text); if (year == 0) { throw new JiBXException("Year value 0 is not allowed"); } if (year > 0) { year--; } long day = ((long)year)*365 + year/4 - year/100 + year/400; return day*MSPERDAY - TIME_BASE; } /** * Parse short value from text. Short values are parsed with optional * leading sign flag, followed by any number of digits. * * @param text text to be parsed * @return converted short value * @throws JiBXException on parse error */ public static short parseShort(String text) throws JiBXException { int value = parseInt(text); if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) { throw new JiBXException("Value out of range"); } return (short)value; } /** * Serialize short value to text. * * @param value short value to be serialized * @return text representation of value */ public static String serializeShort(short value) { return Short.toString(value); } /** * Parse byte value from text. Byte values are parsed with optional * leading sign flag, followed by any number of digits. * * @param text text to be parsed * @return converted byte value * @throws JiBXException on parse error */ public static byte parseByte(String text) throws JiBXException { int value = parseInt(text); if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) { throw new JiBXException("Value out of range"); } return (byte)value; } /** * Serialize byte value to text. * * @param value byte value to be serialized * @return text representation of value */ public static String serializeByte(byte value) { return Byte.toString(value); } /** * Parse boolean value from text. Boolean values are parsed as either text * "true" and "false", or "1" and "0" numeric equivalents. * * @param text text to be parsed * @return converted boolean value * @throws JiBXException on parse error */ public static boolean parseBoolean(String text) throws JiBXException { text = text.trim(); if ("true".equals(text) || "1".equals(text)) { return true; } else if ("false".equals(text) || "0".equals(text)) { return false; } else { throw new JiBXException("Invalid boolean value"); } } /** * Serialize boolean value to text. This serializes the value using the * text representation as "true" or "false". * * @param value boolean value to be serialized * @return text representation of value */ public static String serializeBoolean(boolean value) { return value ? "true" : "false"; } /** * Parse char value from text as unsigned 16-bit integer. Char values are * parsed with optional leading sign flag, followed by any number of digits. * * @param text text to be parsed * @return converted char value * @throws JiBXException on parse error */ public static char parseChar(String text) throws JiBXException {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -