一、前言
关于jibx-run(2.1)源码包中org.jibx.runtime.Utility工具类,进行字符串和基本数据类型相互转换(字符串转布尔型boolean/浮点型float/双精度浮点型double/长整型long/转日期型Date/时间戳Timestamp/字节数组byte[]等)。
二、源码说明
package org.jibx.runtime;@b@@b@import java.sql.Time;@b@import java.sql.Timestamp;@b@import java.util.ArrayList;@b@import java.util.List;@b@import java.util.TimeZone;@b@@b@public abstract class Utility@b@{@b@ private static final int MSPERMINUTE = 60000;@b@ private static final int MSPERHOUR = 3600000;@b@ private static final int MSPERDAY = 86400000;@b@ private static final long LMSPERDAY = 86400000L;@b@ private static final long MSPERYEAR = 31536000000L;@b@ private static final long MSPERAVGYEAR = 31557600000L;@b@ private static final long MSPERCENTURY = 3155695200000L;@b@ private static final long TIME_BASE = 62135596800000L;@b@ private static final int[] MONTHS_NONLEAP = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };@b@ private static final int[] MONTHS_LEAP = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };@b@ private static final long[] BIAS_MONTHMS = { 0L, 0L, 0L, 0L, 2678400000L, 5270400000L, 7948800000L, 10540800000L, 13219200000L, 15897600000L, 18489600000L, 21168000000L, 23760000000L, 26438400000L, 29116800000L };@b@ private static final char PAD_CHAR = 61;@b@ 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', '+', '/' };@b@ private static final byte[] s_base64Values = new byte[128];@b@@b@ private static int parseDigits(String text, int offset, int length)@b@ throws JiBXException@b@ {@b@ int value = 0;@b@ if (length > 9)@b@ {@b@ try@b@ {@b@ value = Integer.parseInt(text.substring(offset, offset + length));@b@ } catch (NumberFormatException ex) {@b@ throw new JiBXException(ex.getMessage());@b@ }@b@@b@ }@b@@b@ int limit = offset + length;@b@ while (offset < limit) {@b@ char chr = text.charAt(offset++);@b@ if ((chr >= '0') && (chr <= '9'))@b@ value = value * 10 + chr - '0';@b@ else {@b@ throw new JiBXException("Non-digit in number value");@b@ }@b@@b@ }@b@@b@ return value;@b@ }@b@@b@ public static int parseInt(String text)@b@ throws JiBXException@b@ {@b@ text = text.trim();@b@ int offset = 0;@b@ int limit = text.length();@b@ if (limit == 0) {@b@ throw new JiBXException("Empty number value");@b@ }@b@@b@ boolean negate = false;@b@ char chr = text.charAt(0);@b@ if (chr == '-') {@b@ if (limit > 9)@b@ {@b@ try@b@ {@b@ return Integer.parseInt(text);@b@ } catch (NumberFormatException ex) {@b@ throw new JiBXException(ex.getMessage());@b@ }@b@ }@b@@b@ negate = true;@b@ ++offset;@b@ }@b@ else if (chr == '+') {@b@ ++offset;@b@ }@b@ if (offset >= limit) {@b@ throw new JiBXException("Invalid number format");@b@ }@b@@b@ int value = parseDigits(text, offset, limit - offset);@b@ if (negate)@b@ return (-value);@b@@b@ return value;@b@ }@b@@b@ public static String serializeInt(int value)@b@ {@b@ return Integer.toString(value);@b@ }@b@@b@ public static long parseLong(String text)@b@ throws JiBXException@b@ {@b@ text = text.trim();@b@ int offset = 0;@b@ int limit = text.length();@b@ if (limit == 0) {@b@ throw new JiBXException("Empty number value");@b@ }@b@@b@ boolean negate = false;@b@ char chr = text.charAt(0);@b@ if (chr == '-') {@b@ negate = true;@b@ ++offset;@b@ } else if (chr == '+') {@b@ ++offset;@b@ }@b@ if (offset >= limit) {@b@ throw new JiBXException("Invalid number format");@b@ }@b@@b@ long value = 0L;@b@ if (limit - offset > 18)@b@ {@b@ if (chr == '+')@b@ text = text.substring(1);@b@ try@b@ {@b@ value = Long.parseLong(text);@b@ } catch (NumberFormatException ex) {@b@ throw new JiBXException(ex.getMessage());@b@ }@b@ }@b@@b@ while (true)@b@ {@b@ if (offset >= limit) break label180;@b@ chr = text.charAt(offset++);@b@ if ((chr < '0') || (chr > '9')) break;@b@ value = value * 10L + chr - '0';@b@ }@b@ throw new JiBXException("Non-digit in number value");@b@@b@ if (negate) {@b@ label180: value = -value;@b@ }@b@@b@ return value;@b@ }@b@@b@ public static String serializeLong(long value)@b@ {@b@ return Long.toString(value);@b@ }@b@@b@ public static short parseShort(String text)@b@ throws JiBXException@b@ {@b@ int value = parseInt(text);@b@ if ((value < -32768) || (value > 32767))@b@ throw new JiBXException("Value out of range");@b@@b@ return (short)value;@b@ }@b@@b@ public static String serializeShort(short value)@b@ {@b@ return Short.toString(value);@b@ }@b@@b@ public static byte parseByte(String text)@b@ throws JiBXException@b@ {@b@ int value = parseInt(text);@b@ if ((value < -128) || (value > 127))@b@ throw new JiBXException("Value out of range");@b@@b@ return (byte)value;@b@ }@b@@b@ public static String serializeByte(byte value)@b@ {@b@ return Byte.toString(value);@b@ }@b@@b@ public static boolean parseBoolean(String text)@b@ throws JiBXException@b@ {@b@ text = text.trim();@b@ if (("true".equals(text)) || ("1".equals(text)))@b@ return true;@b@ if (("false".equals(text)) || ("0".equals(text)))@b@ return false;@b@@b@ throw new JiBXException("Invalid boolean value");@b@ }@b@@b@ public static String serializeBoolean(boolean value)@b@ {@b@ return ((value) ? "true" : "false");@b@ }@b@@b@ public static char parseChar(String text)@b@ throws JiBXException@b@ {@b@ int value = parseInt(text);@b@ if ((value < 0) || (value > 65535))@b@ throw new JiBXException("Value out of range");@b@@b@ return (char)value;@b@ }@b@@b@ public static String serializeChar(char value)@b@ {@b@ return Integer.toString(value);@b@ }@b@@b@ public static char parseCharString(String text)@b@ throws JiBXException@b@ {@b@ if (text.length() == 1)@b@ return text.charAt(0);@b@@b@ throw new JiBXException("Input must be a single character");@b@ }@b@@b@ public static char deserializeCharString(String text)@b@ throws JiBXException@b@ {@b@ if (text == null)@b@ return ';@b@@b@ return parseCharString(text);@b@ }@b@@b@ public static String serializeCharString(char value)@b@ {@b@ return String.valueOf(value);@b@ }@b@@b@ public static float parseFloat(String text)@b@ throws JiBXException@b@ {@b@ text = text.trim();@b@ if ("-INF".equals(text))@b@ return (1.0F / -1.0F);@b@ if ("INF".equals(text))@b@ return (1.0F / 1.0F);@b@ try@b@ {@b@ return Float.parseFloat(text);@b@ } catch (NumberFormatException ex) {@b@ throw new JiBXException(ex.getMessage());@b@ }@b@ }@b@@b@ public static String serializeFloat(float value)@b@ {@b@ if (Float.isInfinite(value))@b@ return ((value < 0.0F) ? "-INF" : "INF");@b@@b@ return Float.toString(value);@b@ }@b@@b@ public static double parseDouble(String text)@b@ throws JiBXException@b@ {@b@ text = text.trim();@b@ if ("-INF".equals(text))@b@ return (-1.0D / 0.0D);@b@ if ("INF".equals(text))@b@ return (1.0D / 0.0D);@b@ try@b@ {@b@ return Double.parseDouble(text);@b@ } catch (NumberFormatException ex) {@b@ throw new JiBXException(ex.getMessage());@b@ }@b@ }@b@@b@ public static String serializeDouble(double value)@b@ {@b@ if (Double.isInfinite(value))@b@ return ((value < 0.0D) ? "-INF" : "INF");@b@@b@ return Double.toString(value);@b@ }@b@@b@ public static long parseYear(String text)@b@ throws JiBXException@b@ {@b@ text = text.trim();@b@ boolean valid = true;@b@ int minc = 4;@b@ char chr = text.charAt(0);@b@ if (chr == '-')@b@ minc = 5;@b@ else if (chr == '+')@b@ valid = false;@b@@b@ if (text.length() < minc)@b@ valid = false;@b@@b@ if (!(valid)) {@b@ throw new JiBXException("Invalid year format");@b@ }@b@@b@ int year = parseInt(text);@b@ if (year == 0)@b@ throw new JiBXException("Year value 0 is not allowed");@b@@b@ if (year > 0)@b@ --year;@b@@b@ long day = year * 365L + year / 4 - year / 100 + year / 400;@b@ return (day * 86400000L - 62135596800000L);@b@ }@b@@b@ public static long parseYearMonth(String text)@b@ throws JiBXException@b@ {@b@ text = text.trim();@b@ boolean valid = true;@b@ int minc = 7;@b@ char chr = text.charAt(0);@b@ if (chr == '-')@b@ minc = 8;@b@ else if (chr == '+')@b@ valid = false;@b@@b@ int split = text.length() - 3;@b@ if (text.length() < minc) {@b@ valid = false;@b@ }@b@ else if (text.charAt(split) != '-') {@b@ valid = false;@b@ }@b@@b@ if (!(valid)) {@b@ throw new JiBXException("Invalid date format");@b@ }@b@@b@ int year = parseInt(text.substring(0, split));@b@ if (year == 0)@b@ throw new JiBXException("Year value 0 is not allowed");@b@@b@ int month = parseDigits(text, split + 1, 2) - 1;@b@ if ((month < 0) || (month > 11))@b@ throw new JiBXException("Month value out of range");@b@@b@ boolean leap = (year % 4 == 0) && (((year % 100 != 0) || (year % 400 == 0)));@b@ if (year > 0)@b@ --year;@b@@b@ long day = year * 365L + year / 4 - year / 100 + year / 400 + MONTHS_NONLEAP[month];@b@@b@ return (day * 86400000L - 62135596800000L);@b@ }@b@@b@ public static long parseDate(String text)@b@ throws JiBXException@b@ {@b@ boolean valid = true;@b@ int minc = 10;@b@ char chr = text.charAt(0);@b@ if (chr == '-')@b@ minc = 11;@b@ else if (chr == '+')@b@ valid = false;@b@@b@ int split = text.length() - 6;@b@ if (text.length() < minc) {@b@ valid = false;@b@ }@b@ else if ((text.charAt(split) != '-') || (text.charAt(split + 3) != '-')) {@b@ valid = false;@b@ }@b@@b@ if (!(valid)) {@b@ throw new JiBXException("Invalid date format");@b@ }@b@@b@ int year = parseInt(text.substring(0, split));@b@ if (year == 0)@b@ throw new JiBXException("Year value 0 is not allowed");@b@@b@ int month = parseDigits(text, split + 1, 2) - 1;@b@ if ((month < 0) || (month > 11))@b@ throw new JiBXException("Month value out of range");@b@@b@ long day = parseDigits(text, split + 4, 2) - 1;@b@ boolean leap = (year % 4 == 0) && (((year % 100 != 0) || (year % 400 == 0)));@b@ int[] starts = (leap) ? MONTHS_LEAP : MONTHS_NONLEAP;@b@ if ((day < 0L) || (day >= starts[(month + 1)] - starts[month]))@b@ throw new JiBXException("Day value out of range");@b@@b@ if (year > 0)@b@ --year;@b@@b@ day += year * 365L + year / 4 - year / 100 + year / 400 + starts[month];@b@ return (day * 86400000L - 62135596800000L);@b@ }@b@@b@ public static java.util.Date deserializeDate(String text)@b@ throws JiBXException@b@ {@b@ if (text == null)@b@ return null;@b@@b@ return new java.util.Date(parseDate(text));@b@ }@b@@b@ public static java.sql.Date deserializeSqlDate(String text)@b@ throws JiBXException@b@ {@b@ if (text == null) {@b@ return null;@b@ }@b@@b@ long time = parseDate(text);@b@ time += TimeZone.getDefault().getRawOffset() + 7200000;@b@ return new java.sql.Date(time);@b@ }@b@@b@ public static long parseTime(String text, int start, int length)@b@ throws JiBXException@b@ {@b@ long milli = 0L;@b@ boolean valid = (length > start + 7) && (text.charAt(start + 2) == ':') && (text.charAt(start + 5) == ':');@b@@b@ if (valid) {@b@ int hour = parseDigits(text, start, 2);@b@ int minute = parseDigits(text, start + 3, 2);@b@ int second = parseDigits(text, start + 6, 2);@b@ if ((hour > 23) || (minute > 59) || (second > 60)) {@b@ valid = false;@b@ }@b@ else@b@ {@b@ milli = ((hour * 60 + minute) * 60 + second) * 1000;@b@ start += 8;@b@ if (length > start)@b@ {@b@ if (text.charAt(length - 1) == 'Z') {@b@ --length;@b@ } else {@b@ char chr = text.charAt(length - 6);@b@ if ((chr == '-') || (chr == '+')) {@b@ hour = parseDigits(text, length - 5, 2);@b@ minute = parseDigits(text, length - 2, 2);@b@ if ((hour > 23) || (minute > 59)) {@b@ valid = false;@b@ } else {@b@ int offset = (hour * 60 + minute) * 60 * 1000;@b@ if (chr == '-')@b@ milli += offset;@b@ else@b@ milli -= offset;@b@ }@b@@b@ length -= 6;@b@ }@b@@b@ }@b@@b@ if (text.charAt(start) == '.') {@b@ double fraction = Double.parseDouble(text.substring(start, length));@b@@b@ milli = ()(milli + fraction * 1000.0D);@b@ } else if (length > start) {@b@ valid = false;@b@ }@b@ }@b@ }@b@@b@ }@b@@b@ if (valid)@b@ return milli;@b@@b@ throw new JiBXException("Invalid dateTime format");@b@ }@b@@b@ public static long parseDateTime(String text)@b@ throws JiBXException@b@ {@b@ int split = text.indexOf(84);@b@ if (split < 0)@b@ throw new JiBXException("Missing 'T' separator in dateTime");@b@@b@ return (parseDate(text.substring(0, split)) + parseTime(text, split + 1, text.length()));@b@ }@b@@b@ public static java.util.Date deserializeDateTime(String text)@b@ throws JiBXException@b@ {@b@ if (text == null)@b@ return null;@b@@b@ return new java.util.Date(parseDateTime(text));@b@ }@b@@b@ public static Timestamp deserializeTimestamp(String text)@b@ throws JiBXException@b@ {@b@ if (text == null) {@b@ return null;@b@ }@b@@b@ int split = text.indexOf(46);@b@ int nano = 0;@b@ if (split > 0)@b@ {@b@ if (text.indexOf(46, split) > 0) {@b@ throw new JiBXException("Not a valid dateTime value");@b@ }@b@@b@ int limit = text.length();@b@ int scan = split;@b@ while (++scan < limit) {@b@ char chr = text.charAt(scan);@b@ if (chr < '0') break; if (chr > '9') {@b@ break;@b@ }@b@@b@ }@b@@b@ int length = scan - split - 1;@b@ if (length > 9)@b@ length = 9;@b@@b@ nano = parseDigits(text, split + 1, length);@b@@b@ while (length < 9) {@b@ nano *= 10;@b@ ++length;@b@ }@b@@b@ if (scan < limit)@b@ text = text.substring(0, split) + text.substring(scan);@b@ else {@b@ text = text.substring(0, split);@b@ }@b@@b@ }@b@@b@ Timestamp stamp = new Timestamp(parseDateTime(text));@b@ stamp.setNanos(nano);@b@ return stamp;@b@ }@b@@b@ public static Time deserializeSqlTime(String text)@b@ throws JiBXException@b@ {@b@ if (text == null)@b@ return null;@b@@b@ return new Time(parseTime(text, 0, text.length()));@b@ }@b@@b@ protected static void formatYearNumber(long year, StringBuffer buff)@b@ {@b@ if (year <= 0L) {@b@ buff.append('-');@b@ year = -(year - 1L);@b@ }@b@@b@ if (year < 1000L) {@b@ buff.append('0');@b@ if (year < 100L) {@b@ buff.append('0');@b@ if (year < 10L)@b@ buff.append('0');@b@@b@ }@b@@b@ }@b@@b@ buff.append(year);@b@ }@b@@b@ protected static void formatTwoDigits(int value, StringBuffer buff)@b@ {@b@ if (value < 10)@b@ buff.append('0');@b@@b@ buff.append(value);@b@ }@b@@b@ protected static void formatYear(long value, StringBuffer buff)@b@ {@b@ long time = value + 26438400000L + 64800000L;@b@ long century = time / 3155695200000L;@b@ long adjusted = time + (century - century / 4L) * 86400000L;@b@ int year = (int)(adjusted / 31557600000L);@b@ if (adjusted < 0L)@b@ --year;@b@@b@ long yms = adjusted + 21600000L - (year * 365 + year / 4) * 86400000L;@b@ int yday = (int)(yms / 86400000L);@b@ int month = (5 * yday + 456) / 153;@b@ if (month > 12) {@b@ ++year;@b@ }@b@@b@ formatYearNumber(year, buff);@b@ }@b@@b@ protected static long formatYearMonth(long value, StringBuffer buff)@b@ {@b@ long time = value + 26438400000L + 64800000L;@b@ long century = time / 3155695200000L;@b@ long adjusted = time + (century - century / 4L) * 86400000L;@b@ int year = (int)(adjusted / 31557600000L);@b@ if (adjusted < 0L)@b@ --year;@b@@b@ long yms = adjusted + 21600000L - (year * 365 + year / 4) * 86400000L;@b@ int yday = (int)(yms / 86400000L);@b@ if (yday == 0) {@b@ boolean bce = year < 0;@b@ if (bce)@b@ --year;@b@@b@ int dcnt = (year % 4 == 0) ? 366 : 365;@b@ if (!(bce))@b@ --year;@b@@b@ yms += dcnt * 86400000L;@b@ yday += dcnt;@b@ }@b@ int month = (5 * yday + 456) / 153;@b@ long rem = yms - BIAS_MONTHMS[month] - 86400000L;@b@ if (month > 12) {@b@ ++year;@b@ month -= 12;@b@ }@b@@b@ formatYearNumber(year, buff);@b@ buff.append('-');@b@ formatTwoDigits(month, buff);@b@@b@ return rem;@b@ }@b@@b@ protected static int formatYearMonthDay(long value, StringBuffer buff)@b@ {@b@ long extra = formatYearMonth(value, buff);@b@@b@ int day = (int)(extra / 86400000L) + 1;@b@ buff.append('-');@b@ formatTwoDigits(day, buff);@b@@b@ return (int)(extra % 86400000L);@b@ }@b@@b@ public static String serializeYear(long time)@b@ throws JiBXException@b@ {@b@ StringBuffer buff = new StringBuffer(6);@b@ formatYear(time + 62135596800000L, buff);@b@ return buff.toString();@b@ }@b@@b@ public static String serializeYear(java.util.Date date)@b@ throws JiBXException@b@ {@b@ return serializeYear(date.getTime());@b@ }@b@@b@ public static String serializeYearMonth(long time)@b@ throws JiBXException@b@ {@b@ StringBuffer buff = new StringBuffer(12);@b@ formatYearMonth(time + 62135596800000L, buff);@b@ return buff.toString();@b@ }@b@@b@ public static String serializeYearMonth(java.util.Date date)@b@ throws JiBXException@b@ {@b@ return serializeYearMonth(date.getTime());@b@ }@b@@b@ public static String serializeDate(long time)@b@ throws JiBXException@b@ {@b@ StringBuffer buff = new StringBuffer(12);@b@ formatYearMonthDay(time + 62135596800000L, buff);@b@ return buff.toString();@b@ }@b@@b@ public static String serializeDate(java.util.Date date)@b@ throws JiBXException@b@ {@b@ return serializeDate(date.getTime());@b@ }@b@@b@ public static String serializeSqlDate(java.sql.Date date)@b@ throws JiBXException@b@ {@b@ long time = date.getTime();@b@ time -= TimeZone.getDefault().getRawOffset() - 7200000;@b@ return serializeDate(time);@b@ }@b@@b@ public static void serializeTime(int time, StringBuffer buff)@b@ throws JiBXException@b@ {@b@ formatTwoDigits(time / 3600000, buff);@b@ time %= 3600000;@b@ buff.append(':');@b@ formatTwoDigits(time / 60000, buff);@b@ time %= 60000;@b@ buff.append(':');@b@ formatTwoDigits(time / 1000, buff);@b@ time %= 1000;@b@@b@ if (time > 0) {@b@ buff.append('.');@b@ buff.append(time / 100);@b@ time %= 100;@b@ if (time > 0) {@b@ buff.append(time / 10);@b@ time %= 10;@b@ if (time > 0)@b@ buff.append(time);@b@ }@b@ }@b@ }@b@@b@ public static String serializeDateTime(long time, boolean zone)@b@ throws JiBXException@b@ {@b@ StringBuffer buff = new StringBuffer(25);@b@ int extra = formatYearMonthDay(time + 62135596800000L, buff);@b@@b@ buff.append('T');@b@ serializeTime(extra, buff);@b@@b@ if (zone)@b@ buff.append('Z');@b@@b@ return buff.toString();@b@ }@b@@b@ public static String serializeDateTime(long time)@b@ throws JiBXException@b@ {@b@ return serializeDateTime(time, false);@b@ }@b@@b@ public static String serializeDateTime(java.util.Date date)@b@ throws JiBXException@b@ {@b@ return serializeDateTime(date.getTime(), false);@b@ }@b@@b@ public static String serializeTimestamp(Timestamp stamp)@b@ throws JiBXException@b@ {@b@ int nano = stamp.getNanos();@b@ if (nano > 0)@b@ {@b@ int i;@b@ String value = serializeInt(nano);@b@@b@ StringBuffer digits = new StringBuffer(9);@b@ if (value.length() < 9) {@b@ int lead = 9 - value.length();@b@ for (i = 0; i < lead; ++i)@b@ digits.append('0');@b@ }@b@@b@ digits.append(value);@b@@b@ int last = 9;@b@ do if (--last <= 0) break;@b@ while (digits.charAt(last) == '0');@b@@b@ digits.setLength(last);@b@@b@ return serializeDateTime(stamp.getTime(), false) + '.' + digits + 'Z';@b@ }@b@@b@ return serializeDateTime(stamp.getTime(), true);@b@ }@b@@b@ public static String serializeSqlTime(Time time)@b@ throws JiBXException@b@ {@b@ StringBuffer buff = new StringBuffer(12);@b@ serializeTime((int)time.getTime(), buff);@b@ return buff.toString();@b@ }@b@@b@ public static boolean isEqual(Object a, Object b)@b@ {@b@ return ((a == null) ? false : (b == null) ? true : a.equals(b));@b@ }@b@@b@ public static int enumValue(String target, String[] enums, int[] vals)@b@ throws JiBXException@b@ {@b@ int base = 0;@b@ int limit = enums.length - 1;@b@ while (base <= limit) {@b@ int cur = base + limit >> 1;@b@ int diff = target.compareTo(enums[cur]);@b@ if (diff < 0) {@b@ limit = cur - 1;@b@ } else if (diff > 0) {@b@ base = cur + 1; } else {@b@ if (vals != null)@b@ return vals[cur];@b@@b@ return cur;@b@ }@b@ }@b@ throw new JiBXException("Target value \"" + target + "\" not found in enumeration");@b@ }@b@@b@ private static int decodeChunk(int base, char[] chrs, int fill, byte[] byts)@b@ throws JiBXException@b@ {@b@ int length = 3;@b@ if (chrs[(base + 3)] == '=') {@b@ length = 2;@b@ if (chrs[(base + 2)] == '=') {@b@ length = 1;@b@ }@b@@b@ }@b@@b@ int v0 = s_base64Values[chrs[(base + 0)]];@b@ int v1 = s_base64Values[chrs[(base + 1)]];@b@ int v2 = s_base64Values[chrs[(base + 2)]];@b@ int v3 = s_base64Values[chrs[(base + 3)]];@b@@b@ switch (length)@b@ {@b@ case 3:@b@ byts[(fill + 2)] = (byte)(v2 << 6 | v3);@b@ case 2:@b@ byts[(fill + 1)] = (byte)(v1 << 4 | v2 >> 2);@b@ case 1:@b@ byts[fill] = (byte)(v0 << 2 | v1 >> 4);@b@ }@b@@b@ return length;@b@ }@b@@b@ public static byte[] parseBase64(String text)@b@ throws JiBXException@b@ {@b@ char[] chrs = new char[text.length()];@b@ int length = 0;@b@ for (int i = 0; i < text.length(); ++i) {@b@ char chr = text.charAt(i);@b@ if ((chr < 128) && (s_base64Values[chr] >= 0)) {@b@ chrs[(length++)] = chr;@b@ }@b@@b@ }@b@@b@ if (length % 4 != 0)@b@ throw new JiBXException("Text length for base64 must be a multiple of 4");@b@@b@ if (length == 0) {@b@ return new byte[0];@b@ }@b@@b@ int blength = length / 4 * 3;@b@ if (chrs[(length - 1)] == '=') {@b@ --blength;@b@ if (chrs[(length - 2)] == '=') {@b@ --blength;@b@ }@b@@b@ }@b@@b@ byte[] byts = new byte[blength];@b@ int fill = 0;@b@ for (int i = 0; i < length; i += 4)@b@ fill += decodeChunk(i, chrs, fill, byts);@b@@b@ if (fill != blength) {@b@ throw new JiBXException("Embedded padding characters in byte64 text");@b@ }@b@@b@ return byts;@b@ }@b@@b@ public static byte[] deserializeBase64(String text)@b@ throws JiBXException@b@ {@b@ if (text == null)@b@ return null;@b@@b@ return parseBase64(text);@b@ }@b@@b@ public static void encodeChunk(int base, byte[] byts, StringBuffer buff)@b@ {@b@ int length = 3;@b@ if (base + length > byts.length) {@b@ length = byts.length - base;@b@ }@b@@b@ int b0 = byts[base];@b@ int value = b0 >> 2 & 0x3F;@b@ buff.append(s_base64Chars[value]);@b@ if (length > 1) {@b@ int b1 = byts[(base + 1)];@b@ value = ((b0 & 0x3) << 4) + (b1 >> 4 & 0xF);@b@ buff.append(s_base64Chars[value]);@b@ if (length > 2) {@b@ int b2 = byts[(base + 2)];@b@ value = ((b1 & 0xF) << 2) + (b2 >> 6 & 0x3);@b@ buff.append(s_base64Chars[value]);@b@ value = b2 & 0x3F;@b@ buff.append(s_base64Chars[value]);@b@ } else {@b@ value = (b1 & 0xF) << 2;@b@ buff.append(s_base64Chars[value]);@b@ buff.append('=');@b@ }@b@ } else {@b@ value = (b0 & 0x3) << 4;@b@ buff.append(s_base64Chars[value]);@b@ buff.append('=');@b@ buff.append('=');@b@ }@b@ }@b@@b@ public static String serializeBase64(byte[] byts)@b@ {@b@ StringBuffer buff = new StringBuffer((byts.length + 2) / 3 * 4);@b@ for (int i = 0; i < byts.length; i += 3) {@b@ encodeChunk(i, byts, buff);@b@ if ((i > 0) && (i % 57 == 0) && (i + 3 < byts.length))@b@ buff.append("\r\n");@b@ }@b@@b@ return buff.toString();@b@ }@b@@b@ public static List arrayListFactory()@b@ {@b@ return new ArrayList();@b@ }@b@@b@ static@b@ {@b@ for (int i = 0; i < s_base64Values.length; ++i)@b@ s_base64Values[i] = -1;@b@@b@ s_base64Values[61] = 0;@b@ for (i = 0; i < s_base64Chars.length; ++i)@b@ s_base64Values[s_base64Chars[i]] = (byte)i;@b@ }@b@}