src/share/jaxws_classes/com/sun/xml/internal/bind/DatatypeConverterImpl.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 514
29a761eaff0d
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.xml.internal.bind;
aoqi@0 27
aoqi@0 28 import java.math.BigDecimal;
aoqi@0 29 import java.math.BigInteger;
aoqi@0 30 import java.security.AccessController;
aoqi@0 31 import java.security.PrivilegedAction;
aoqi@0 32 import java.util.Calendar;
aoqi@0 33 import java.util.Collections;
aoqi@0 34 import java.util.GregorianCalendar;
aoqi@0 35 import java.util.Map;
aoqi@0 36 import java.util.TimeZone;
aoqi@0 37 import java.util.WeakHashMap;
aoqi@0 38
aoqi@0 39 import javax.xml.bind.DatatypeConverter;
aoqi@0 40 import javax.xml.bind.DatatypeConverterInterface;
aoqi@0 41 import javax.xml.datatype.DatatypeConfigurationException;
aoqi@0 42 import javax.xml.datatype.DatatypeFactory;
aoqi@0 43 import javax.xml.namespace.NamespaceContext;
aoqi@0 44 import javax.xml.namespace.QName;
aoqi@0 45 import javax.xml.stream.XMLStreamException;
aoqi@0 46 import javax.xml.stream.XMLStreamWriter;
aoqi@0 47
aoqi@0 48 /**
aoqi@0 49 * This class is the JAXB RI's default implementation of the
aoqi@0 50 * {@link DatatypeConverterInterface}.
aoqi@0 51 *
aoqi@0 52 * <p>
aoqi@0 53 * When client applications specify the use of the static print/parse
aoqi@0 54 * methods in {@link DatatypeConverter}, it will delegate
aoqi@0 55 * to this class.
aoqi@0 56 *
aoqi@0 57 * <p>
aoqi@0 58 * This class is responsible for whitespace normalization.
aoqi@0 59 *
aoqi@0 60 * @author <ul><li>Ryan Shoemaker, Martin Grebac</li></ul>
aoqi@0 61 * @since JAXB1.0
aoqi@0 62 * @deprecated in JAXB 2.2.4 - use javax.xml.bind.DatatypeConverterImpl instead
aoqi@0 63 * or let us know why you can't
aoqi@0 64 */
aoqi@0 65 @Deprecated
aoqi@0 66 public final class DatatypeConverterImpl implements DatatypeConverterInterface {
aoqi@0 67
aoqi@0 68 @Deprecated
aoqi@0 69 public static final DatatypeConverterInterface theInstance = new DatatypeConverterImpl();
aoqi@0 70
aoqi@0 71 protected DatatypeConverterImpl() {
aoqi@0 72 // shall not be used
aoqi@0 73 }
aoqi@0 74
aoqi@0 75 public static BigInteger _parseInteger(CharSequence s) {
aoqi@0 76 return new BigInteger(removeOptionalPlus(WhiteSpaceProcessor.trim(s)).toString());
aoqi@0 77 }
aoqi@0 78
aoqi@0 79 public static String _printInteger(BigInteger val) {
aoqi@0 80 return val.toString();
aoqi@0 81 }
aoqi@0 82
aoqi@0 83 /**
aoqi@0 84 * Faster but less robust String->int conversion.
aoqi@0 85 *
aoqi@0 86 * Note that:
aoqi@0 87 * <ol>
aoqi@0 88 * <li>XML Schema allows '+', but {@link Integer#valueOf(String)} is not.
aoqi@0 89 * <li>XML Schema allows leading and trailing (but not in-between) whitespaces.
aoqi@0 90 * {@link Integer#valueOf(String)} doesn't allow any.
aoqi@0 91 * </ol>
aoqi@0 92 */
aoqi@0 93 public static int _parseInt(CharSequence s) {
aoqi@0 94 int len = s.length();
aoqi@0 95 int sign = 1;
aoqi@0 96
aoqi@0 97 int r = 0;
aoqi@0 98
aoqi@0 99 for (int i = 0; i < len; i++) {
aoqi@0 100 char ch = s.charAt(i);
aoqi@0 101 if (WhiteSpaceProcessor.isWhiteSpace(ch)) {
aoqi@0 102 // skip whitespace
aoqi@0 103 } else if ('0' <= ch && ch <= '9') {
aoqi@0 104 r = r * 10 + (ch - '0');
aoqi@0 105 } else if (ch == '-') {
aoqi@0 106 sign = -1;
aoqi@0 107 } else if (ch == '+') {
aoqi@0 108 // noop
aoqi@0 109 } else {
aoqi@0 110 throw new NumberFormatException("Not a number: " + s);
aoqi@0 111 }
aoqi@0 112 }
aoqi@0 113
aoqi@0 114 return r * sign;
aoqi@0 115 }
aoqi@0 116
aoqi@0 117 public static long _parseLong(CharSequence s) {
aoqi@0 118 return Long.valueOf(removeOptionalPlus(WhiteSpaceProcessor.trim(s)).toString());
aoqi@0 119 }
aoqi@0 120
aoqi@0 121 public static short _parseShort(CharSequence s) {
aoqi@0 122 return (short) _parseInt(s);
aoqi@0 123 }
aoqi@0 124
aoqi@0 125 public static String _printShort(short val) {
aoqi@0 126 return String.valueOf(val);
aoqi@0 127 }
aoqi@0 128
aoqi@0 129 public static BigDecimal _parseDecimal(CharSequence content) {
aoqi@0 130 content = WhiteSpaceProcessor.trim(content);
aoqi@0 131
aoqi@0 132 if (content.length() <= 0) {
aoqi@0 133 return null;
aoqi@0 134 }
aoqi@0 135
aoqi@0 136 return new BigDecimal(content.toString());
aoqi@0 137
aoqi@0 138 // from purely XML Schema perspective,
aoqi@0 139 // this implementation has a problem, since
aoqi@0 140 // in xs:decimal "1.0" and "1" is equal whereas the above
aoqi@0 141 // code will return different values for those two forms.
aoqi@0 142 //
aoqi@0 143 // the code was originally using com.sun.msv.datatype.xsd.NumberType.load,
aoqi@0 144 // but a profiling showed that the process of normalizing "1.0" into "1"
aoqi@0 145 // could take non-trivial time.
aoqi@0 146 //
aoqi@0 147 // also, from the user's point of view, one might be surprised if
aoqi@0 148 // 1 (not 1.0) is returned from "1.000"
aoqi@0 149 }
aoqi@0 150
aoqi@0 151 public static float _parseFloat(CharSequence _val) {
aoqi@0 152 String s = WhiteSpaceProcessor.trim(_val).toString();
aoqi@0 153 /* Incompatibilities of XML Schema's float "xfloat" and Java's float "jfloat"
aoqi@0 154
aoqi@0 155 * jfloat.valueOf ignores leading and trailing whitespaces,
aoqi@0 156 whereas this is not allowed in xfloat.
aoqi@0 157 * jfloat.valueOf allows "float type suffix" (f, F) to be
aoqi@0 158 appended after float literal (e.g., 1.52e-2f), whereare
aoqi@0 159 this is not the case of xfloat.
aoqi@0 160
aoqi@0 161 gray zone
aoqi@0 162 ---------
aoqi@0 163 * jfloat allows ".523". And there is no clear statement that mentions
aoqi@0 164 this case in xfloat. Although probably this is allowed.
aoqi@0 165 *
aoqi@0 166 */
aoqi@0 167
aoqi@0 168 if (s.equals("NaN")) {
aoqi@0 169 return Float.NaN;
aoqi@0 170 }
aoqi@0 171 if (s.equals("INF")) {
aoqi@0 172 return Float.POSITIVE_INFINITY;
aoqi@0 173 }
aoqi@0 174 if (s.equals("-INF")) {
aoqi@0 175 return Float.NEGATIVE_INFINITY;
aoqi@0 176 }
aoqi@0 177
aoqi@0 178 if (s.length() == 0
aoqi@0 179 || !isDigitOrPeriodOrSign(s.charAt(0))
aoqi@0 180 || !isDigitOrPeriodOrSign(s.charAt(s.length() - 1))) {
aoqi@0 181 throw new NumberFormatException();
aoqi@0 182 }
aoqi@0 183
aoqi@0 184 // these screening process is necessary due to the wobble of Float.valueOf method
aoqi@0 185 return Float.parseFloat(s);
aoqi@0 186 }
aoqi@0 187
aoqi@0 188 public static String _printFloat(float v) {
aoqi@0 189 if (Float.isNaN(v)) {
aoqi@0 190 return "NaN";
aoqi@0 191 }
aoqi@0 192 if (v == Float.POSITIVE_INFINITY) {
aoqi@0 193 return "INF";
aoqi@0 194 }
aoqi@0 195 if (v == Float.NEGATIVE_INFINITY) {
aoqi@0 196 return "-INF";
aoqi@0 197 }
aoqi@0 198 return String.valueOf(v);
aoqi@0 199 }
aoqi@0 200
aoqi@0 201 public static double _parseDouble(CharSequence _val) {
aoqi@0 202 String val = WhiteSpaceProcessor.trim(_val).toString();
aoqi@0 203
aoqi@0 204 if (val.equals("NaN")) {
aoqi@0 205 return Double.NaN;
aoqi@0 206 }
aoqi@0 207 if (val.equals("INF")) {
aoqi@0 208 return Double.POSITIVE_INFINITY;
aoqi@0 209 }
aoqi@0 210 if (val.equals("-INF")) {
aoqi@0 211 return Double.NEGATIVE_INFINITY;
aoqi@0 212 }
aoqi@0 213
aoqi@0 214 if (val.length() == 0
aoqi@0 215 || !isDigitOrPeriodOrSign(val.charAt(0))
aoqi@0 216 || !isDigitOrPeriodOrSign(val.charAt(val.length() - 1))) {
aoqi@0 217 throw new NumberFormatException(val);
aoqi@0 218 }
aoqi@0 219
aoqi@0 220
aoqi@0 221 // these screening process is necessary due to the wobble of Float.valueOf method
aoqi@0 222 return Double.parseDouble(val);
aoqi@0 223 }
aoqi@0 224
aoqi@0 225 public static Boolean _parseBoolean(CharSequence literal) {
aoqi@0 226 if (literal == null) {
aoqi@0 227 return null;
aoqi@0 228 }
aoqi@0 229
aoqi@0 230 int i = 0;
aoqi@0 231 int len = literal.length();
aoqi@0 232 char ch;
aoqi@0 233 boolean value = false;
aoqi@0 234
aoqi@0 235 if (literal.length() <= 0) {
aoqi@0 236 return null;
aoqi@0 237 }
aoqi@0 238
aoqi@0 239 do {
aoqi@0 240 ch = literal.charAt(i++);
aoqi@0 241 } while (WhiteSpaceProcessor.isWhiteSpace(ch) && i < len);
aoqi@0 242
aoqi@0 243 int strIndex = 0;
aoqi@0 244
aoqi@0 245 switch (ch) {
aoqi@0 246 case '1':
aoqi@0 247 value = true;
aoqi@0 248 break;
aoqi@0 249 case '0':
aoqi@0 250 value = false;
aoqi@0 251 break;
aoqi@0 252 case 't':
aoqi@0 253 String strTrue = "rue";
aoqi@0 254 do {
aoqi@0 255 ch = literal.charAt(i++);
aoqi@0 256 } while ((strTrue.charAt(strIndex++) == ch) && i < len && strIndex < 3);
aoqi@0 257
aoqi@0 258 if (strIndex == 3) {
aoqi@0 259 value = true;
aoqi@0 260 } else {
aoqi@0 261 return false;
aoqi@0 262 }
aoqi@0 263 // throw new IllegalArgumentException("String \"" + literal + "\" is not valid boolean value.");
aoqi@0 264
aoqi@0 265 break;
aoqi@0 266 case 'f':
aoqi@0 267 String strFalse = "alse";
aoqi@0 268 do {
aoqi@0 269 ch = literal.charAt(i++);
aoqi@0 270 } while ((strFalse.charAt(strIndex++) == ch) && i < len && strIndex < 4);
aoqi@0 271
aoqi@0 272
aoqi@0 273 if (strIndex == 4) {
aoqi@0 274 value = false;
aoqi@0 275 } else {
aoqi@0 276 return false;
aoqi@0 277 }
aoqi@0 278 // throw new IllegalArgumentException("String \"" + literal + "\" is not valid boolean value.");
aoqi@0 279
aoqi@0 280 break;
aoqi@0 281 }
aoqi@0 282
aoqi@0 283 if (i < len) {
aoqi@0 284 do {
aoqi@0 285 ch = literal.charAt(i++);
aoqi@0 286 } while (WhiteSpaceProcessor.isWhiteSpace(ch) && i < len);
aoqi@0 287 }
aoqi@0 288
aoqi@0 289 if (i == len) {
aoqi@0 290 return value;
aoqi@0 291 } else {
aoqi@0 292 return null;
aoqi@0 293 }
aoqi@0 294 // throw new IllegalArgumentException("String \"" + literal + "\" is not valid boolean value.");
aoqi@0 295 }
aoqi@0 296
aoqi@0 297 public static String _printBoolean(boolean val) {
aoqi@0 298 return val ? "true" : "false";
aoqi@0 299 }
aoqi@0 300
aoqi@0 301 public static byte _parseByte(CharSequence literal) {
aoqi@0 302 return (byte) _parseInt(literal);
aoqi@0 303 }
aoqi@0 304
aoqi@0 305 public static String _printByte(byte val) {
aoqi@0 306 return String.valueOf(val);
aoqi@0 307 }
aoqi@0 308
aoqi@0 309 /**
aoqi@0 310 * @return null if fails to convert.
aoqi@0 311 */
aoqi@0 312 public static QName _parseQName(CharSequence text, NamespaceContext nsc) {
aoqi@0 313 int length = text.length();
aoqi@0 314
aoqi@0 315 // trim whitespace
aoqi@0 316 int start = 0;
aoqi@0 317 while (start < length && WhiteSpaceProcessor.isWhiteSpace(text.charAt(start))) {
aoqi@0 318 start++;
aoqi@0 319 }
aoqi@0 320
aoqi@0 321 int end = length;
aoqi@0 322 while (end > start && WhiteSpaceProcessor.isWhiteSpace(text.charAt(end - 1))) {
aoqi@0 323 end--;
aoqi@0 324 }
aoqi@0 325
aoqi@0 326 if (end == start) {
aoqi@0 327 throw new IllegalArgumentException("input is empty");
aoqi@0 328 }
aoqi@0 329
aoqi@0 330
aoqi@0 331 String uri;
aoqi@0 332 String localPart;
aoqi@0 333 String prefix;
aoqi@0 334
aoqi@0 335 // search ':'
aoqi@0 336 int idx = start + 1; // no point in searching the first char. that's not valid.
aoqi@0 337 while (idx < end && text.charAt(idx) != ':') {
aoqi@0 338 idx++;
aoqi@0 339 }
aoqi@0 340
aoqi@0 341 if (idx == end) {
aoqi@0 342 uri = nsc.getNamespaceURI("");
aoqi@0 343 localPart = text.subSequence(start, end).toString();
aoqi@0 344 prefix = "";
aoqi@0 345 } else {
aoqi@0 346 // Prefix exists, check everything
aoqi@0 347 prefix = text.subSequence(start, idx).toString();
aoqi@0 348 localPart = text.subSequence(idx + 1, end).toString();
aoqi@0 349 uri = nsc.getNamespaceURI(prefix);
aoqi@0 350 // uri can never be null according to javadoc,
aoqi@0 351 // but some users reported that there are implementations that return null.
aoqi@0 352 if (uri == null || uri.length() == 0) // crap. the NamespaceContext interface is broken.
aoqi@0 353 // error: unbound prefix
aoqi@0 354 {
aoqi@0 355 throw new IllegalArgumentException("prefix " + prefix + " is not bound to a namespace");
aoqi@0 356 }
aoqi@0 357 }
aoqi@0 358
aoqi@0 359 return new QName(uri, localPart, prefix);
aoqi@0 360 }
aoqi@0 361
aoqi@0 362 public static GregorianCalendar _parseDateTime(CharSequence s) {
aoqi@0 363 String val = WhiteSpaceProcessor.trim(s).toString();
aoqi@0 364 return getDatatypeFactory().newXMLGregorianCalendar(val).toGregorianCalendar();
aoqi@0 365 }
aoqi@0 366
aoqi@0 367 public static String _printDateTime(Calendar val) {
aoqi@0 368 return CalendarFormatter.doFormat("%Y-%M-%DT%h:%m:%s%z", val);
aoqi@0 369 }
aoqi@0 370
aoqi@0 371 public static String _printDate(Calendar val) {
aoqi@0 372 return CalendarFormatter.doFormat((new StringBuilder("%Y-%M-%D").append("%z")).toString(),val);
aoqi@0 373 }
aoqi@0 374
aoqi@0 375 public static String _printInt(int val) {
aoqi@0 376 return String.valueOf(val);
aoqi@0 377 }
aoqi@0 378
aoqi@0 379 public static String _printLong(long val) {
aoqi@0 380 return String.valueOf(val);
aoqi@0 381 }
aoqi@0 382
aoqi@0 383 public static String _printDecimal(BigDecimal val) {
aoqi@0 384 return val.toPlainString();
aoqi@0 385 }
aoqi@0 386
aoqi@0 387 public static String _printDouble(double v) {
aoqi@0 388 if (Double.isNaN(v)) {
aoqi@0 389 return "NaN";
aoqi@0 390 }
aoqi@0 391 if (v == Double.POSITIVE_INFINITY) {
aoqi@0 392 return "INF";
aoqi@0 393 }
aoqi@0 394 if (v == Double.NEGATIVE_INFINITY) {
aoqi@0 395 return "-INF";
aoqi@0 396 }
aoqi@0 397 return String.valueOf(v);
aoqi@0 398 }
aoqi@0 399
aoqi@0 400 public static String _printQName(QName val, NamespaceContext nsc) {
aoqi@0 401 // Double-check
aoqi@0 402 String qname;
aoqi@0 403 String prefix = nsc.getPrefix(val.getNamespaceURI());
aoqi@0 404 String localPart = val.getLocalPart();
aoqi@0 405
aoqi@0 406 if (prefix == null || prefix.length() == 0) { // be defensive
aoqi@0 407 qname = localPart;
aoqi@0 408 } else {
aoqi@0 409 qname = prefix + ':' + localPart;
aoqi@0 410 }
aoqi@0 411
aoqi@0 412 return qname;
aoqi@0 413 }
aoqi@0 414
aoqi@0 415 // base64 decoder
aoqi@0 416 private static final byte[] decodeMap = initDecodeMap();
aoqi@0 417 private static final byte PADDING = 127;
aoqi@0 418
aoqi@0 419 private static byte[] initDecodeMap() {
aoqi@0 420 byte[] map = new byte[128];
aoqi@0 421 int i;
aoqi@0 422 for (i = 0; i < 128; i++) {
aoqi@0 423 map[i] = -1;
aoqi@0 424 }
aoqi@0 425
aoqi@0 426 for (i = 'A'; i <= 'Z'; i++) {
aoqi@0 427 map[i] = (byte) (i - 'A');
aoqi@0 428 }
aoqi@0 429 for (i = 'a'; i <= 'z'; i++) {
aoqi@0 430 map[i] = (byte) (i - 'a' + 26);
aoqi@0 431 }
aoqi@0 432 for (i = '0'; i <= '9'; i++) {
aoqi@0 433 map[i] = (byte) (i - '0' + 52);
aoqi@0 434 }
aoqi@0 435 map['+'] = 62;
aoqi@0 436 map['/'] = 63;
aoqi@0 437 map['='] = PADDING;
aoqi@0 438
aoqi@0 439 return map;
aoqi@0 440 }
aoqi@0 441
aoqi@0 442 /**
aoqi@0 443 * computes the length of binary data speculatively.
aoqi@0 444 *
aoqi@0 445 * <p>
aoqi@0 446 * Our requirement is to create byte[] of the exact length to store the binary data.
aoqi@0 447 * If we do this in a straight-forward way, it takes two passes over the data.
aoqi@0 448 * Experiments show that this is a non-trivial overhead (35% or so is spent on
aoqi@0 449 * the first pass in calculating the length.)
aoqi@0 450 *
aoqi@0 451 * <p>
aoqi@0 452 * So the approach here is that we compute the length speculatively, without looking
aoqi@0 453 * at the whole contents. The obtained speculative value is never less than the
aoqi@0 454 * actual length of the binary data, but it may be bigger. So if the speculation
aoqi@0 455 * goes wrong, we'll pay the cost of reallocation and buffer copying.
aoqi@0 456 *
aoqi@0 457 * <p>
aoqi@0 458 * If the base64 text is tightly packed with no indentation nor illegal char
aoqi@0 459 * (like what most web services produce), then the speculation of this method
aoqi@0 460 * will be correct, so we get the performance benefit.
aoqi@0 461 */
aoqi@0 462 private static int guessLength(String text) {
aoqi@0 463 final int len = text.length();
aoqi@0 464
aoqi@0 465 // compute the tail '=' chars
aoqi@0 466 int j = len - 1;
aoqi@0 467 for (; j >= 0; j--) {
aoqi@0 468 byte code = decodeMap[text.charAt(j)];
aoqi@0 469 if (code == PADDING) {
aoqi@0 470 continue;
aoqi@0 471 }
aoqi@0 472 if (code == -1) // most likely this base64 text is indented. go with the upper bound
aoqi@0 473 {
aoqi@0 474 return text.length() / 4 * 3;
aoqi@0 475 }
aoqi@0 476 break;
aoqi@0 477 }
aoqi@0 478
aoqi@0 479 j++; // text.charAt(j) is now at some base64 char, so +1 to make it the size
aoqi@0 480 int padSize = len - j;
aoqi@0 481 if (padSize > 2) // something is wrong with base64. be safe and go with the upper bound
aoqi@0 482 {
aoqi@0 483 return text.length() / 4 * 3;
aoqi@0 484 }
aoqi@0 485
aoqi@0 486 // so far this base64 looks like it's unindented tightly packed base64.
aoqi@0 487 // take a chance and create an array with the expected size
aoqi@0 488 return text.length() / 4 * 3 - padSize;
aoqi@0 489 }
aoqi@0 490
aoqi@0 491 /**
aoqi@0 492 * @param text
aoqi@0 493 * base64Binary data is likely to be long, and decoding requires
aoqi@0 494 * each character to be accessed twice (once for counting length, another
aoqi@0 495 * for decoding.)
aoqi@0 496 *
aoqi@0 497 * A benchmark showed that taking {@link String} is faster, presumably
aoqi@0 498 * because JIT can inline a lot of string access (with data of 1K chars, it was twice as fast)
aoqi@0 499 */
aoqi@0 500 public static byte[] _parseBase64Binary(String text) {
aoqi@0 501 final int buflen = guessLength(text);
aoqi@0 502 final byte[] out = new byte[buflen];
aoqi@0 503 int o = 0;
aoqi@0 504
aoqi@0 505 final int len = text.length();
aoqi@0 506 int i;
aoqi@0 507
aoqi@0 508 final byte[] quadruplet = new byte[4];
aoqi@0 509 int q = 0;
aoqi@0 510
aoqi@0 511 // convert each quadruplet to three bytes.
aoqi@0 512 for (i = 0; i < len; i++) {
aoqi@0 513 char ch = text.charAt(i);
aoqi@0 514 byte v = decodeMap[ch];
aoqi@0 515
aoqi@0 516 if (v != -1) {
aoqi@0 517 quadruplet[q++] = v;
aoqi@0 518 }
aoqi@0 519
aoqi@0 520 if (q == 4) {
aoqi@0 521 // quadruplet is now filled.
aoqi@0 522 out[o++] = (byte) ((quadruplet[0] << 2) | (quadruplet[1] >> 4));
aoqi@0 523 if (quadruplet[2] != PADDING) {
aoqi@0 524 out[o++] = (byte) ((quadruplet[1] << 4) | (quadruplet[2] >> 2));
aoqi@0 525 }
aoqi@0 526 if (quadruplet[3] != PADDING) {
aoqi@0 527 out[o++] = (byte) ((quadruplet[2] << 6) | (quadruplet[3]));
aoqi@0 528 }
aoqi@0 529 q = 0;
aoqi@0 530 }
aoqi@0 531 }
aoqi@0 532
aoqi@0 533 if (buflen == o) // speculation worked out to be OK
aoqi@0 534 {
aoqi@0 535 return out;
aoqi@0 536 }
aoqi@0 537
aoqi@0 538 // we overestimated, so need to create a new buffer
aoqi@0 539 byte[] nb = new byte[o];
aoqi@0 540 System.arraycopy(out, 0, nb, 0, o);
aoqi@0 541 return nb;
aoqi@0 542 }
aoqi@0 543 private static final char[] encodeMap = initEncodeMap();
aoqi@0 544
aoqi@0 545 private static char[] initEncodeMap() {
aoqi@0 546 char[] map = new char[64];
aoqi@0 547 int i;
aoqi@0 548 for (i = 0; i < 26; i++) {
aoqi@0 549 map[i] = (char) ('A' + i);
aoqi@0 550 }
aoqi@0 551 for (i = 26; i < 52; i++) {
aoqi@0 552 map[i] = (char) ('a' + (i - 26));
aoqi@0 553 }
aoqi@0 554 for (i = 52; i < 62; i++) {
aoqi@0 555 map[i] = (char) ('0' + (i - 52));
aoqi@0 556 }
aoqi@0 557 map[62] = '+';
aoqi@0 558 map[63] = '/';
aoqi@0 559
aoqi@0 560 return map;
aoqi@0 561 }
aoqi@0 562
aoqi@0 563 public static char encode(int i) {
aoqi@0 564 return encodeMap[i & 0x3F];
aoqi@0 565 }
aoqi@0 566
aoqi@0 567 public static byte encodeByte(int i) {
aoqi@0 568 return (byte) encodeMap[i & 0x3F];
aoqi@0 569 }
aoqi@0 570
aoqi@0 571 public static String _printBase64Binary(byte[] input) {
aoqi@0 572 return _printBase64Binary(input, 0, input.length);
aoqi@0 573 }
aoqi@0 574
aoqi@0 575 public static String _printBase64Binary(byte[] input, int offset, int len) {
aoqi@0 576 char[] buf = new char[((len + 2) / 3) * 4];
aoqi@0 577 int ptr = _printBase64Binary(input, offset, len, buf, 0);
aoqi@0 578 assert ptr == buf.length;
aoqi@0 579 return new String(buf);
aoqi@0 580 }
aoqi@0 581
aoqi@0 582 /**
aoqi@0 583 * Encodes a byte array into a char array by doing base64 encoding.
aoqi@0 584 *
aoqi@0 585 * The caller must supply a big enough buffer.
aoqi@0 586 *
aoqi@0 587 * @return
aoqi@0 588 * the value of {@code ptr+((len+2)/3)*4}, which is the new offset
aoqi@0 589 * in the output buffer where the further bytes should be placed.
aoqi@0 590 */
aoqi@0 591 public static int _printBase64Binary(byte[] input, int offset, int len, char[] buf, int ptr) {
aoqi@0 592 // encode elements until only 1 or 2 elements are left to encode
aoqi@0 593 int remaining = len;
aoqi@0 594 int i;
aoqi@0 595 for (i = offset;remaining >= 3; remaining -= 3, i += 3) {
aoqi@0 596 buf[ptr++] = encode(input[i] >> 2);
aoqi@0 597 buf[ptr++] = encode(
aoqi@0 598 ((input[i] & 0x3) << 4)
aoqi@0 599 | ((input[i + 1] >> 4) & 0xF));
aoqi@0 600 buf[ptr++] = encode(
aoqi@0 601 ((input[i + 1] & 0xF) << 2)
aoqi@0 602 | ((input[i + 2] >> 6) & 0x3));
aoqi@0 603 buf[ptr++] = encode(input[i + 2] & 0x3F);
aoqi@0 604 }
aoqi@0 605 // encode when exactly 1 element (left) to encode
aoqi@0 606 if (remaining == 1) {
aoqi@0 607 buf[ptr++] = encode(input[i] >> 2);
aoqi@0 608 buf[ptr++] = encode(((input[i]) & 0x3) << 4);
aoqi@0 609 buf[ptr++] = '=';
aoqi@0 610 buf[ptr++] = '=';
aoqi@0 611 }
aoqi@0 612 // encode when exactly 2 elements (left) to encode
aoqi@0 613 if (remaining == 2) {
aoqi@0 614 buf[ptr++] = encode(input[i] >> 2);
aoqi@0 615 buf[ptr++] = encode(((input[i] & 0x3) << 4)
aoqi@0 616 | ((input[i + 1] >> 4) & 0xF));
aoqi@0 617 buf[ptr++] = encode((input[i + 1] & 0xF) << 2);
aoqi@0 618 buf[ptr++] = '=';
aoqi@0 619 }
aoqi@0 620 return ptr;
aoqi@0 621 }
aoqi@0 622
aoqi@0 623 public static void _printBase64Binary(byte[] input, int offset, int len, XMLStreamWriter output) throws XMLStreamException {
aoqi@0 624 int remaining = len;
aoqi@0 625 int i;
aoqi@0 626 char[] buf = new char[4];
aoqi@0 627
aoqi@0 628 for (i = offset; remaining >= 3; remaining -= 3, i += 3) {
aoqi@0 629 buf[0] = encode(input[i] >> 2);
aoqi@0 630 buf[1] = encode(
aoqi@0 631 ((input[i] & 0x3) << 4)
aoqi@0 632 | ((input[i + 1] >> 4) & 0xF));
aoqi@0 633 buf[2] = encode(
aoqi@0 634 ((input[i + 1] & 0xF) << 2)
aoqi@0 635 | ((input[i + 2] >> 6) & 0x3));
aoqi@0 636 buf[3] = encode(input[i + 2] & 0x3F);
aoqi@0 637 output.writeCharacters(buf, 0, 4);
aoqi@0 638 }
aoqi@0 639 // encode when exactly 1 element (left) to encode
aoqi@0 640 if (remaining == 1) {
aoqi@0 641 buf[0] = encode(input[i] >> 2);
aoqi@0 642 buf[1] = encode(((input[i]) & 0x3) << 4);
aoqi@0 643 buf[2] = '=';
aoqi@0 644 buf[3] = '=';
aoqi@0 645 output.writeCharacters(buf, 0, 4);
aoqi@0 646 }
aoqi@0 647 // encode when exactly 2 elements (left) to encode
aoqi@0 648 if (remaining == 2) {
aoqi@0 649 buf[0] = encode(input[i] >> 2);
aoqi@0 650 buf[1] = encode(((input[i] & 0x3) << 4)
aoqi@0 651 | ((input[i + 1] >> 4) & 0xF));
aoqi@0 652 buf[2] = encode((input[i + 1] & 0xF) << 2);
aoqi@0 653 buf[3] = '=';
aoqi@0 654 output.writeCharacters(buf, 0, 4);
aoqi@0 655 }
aoqi@0 656 }
aoqi@0 657
aoqi@0 658 /**
aoqi@0 659 * Encodes a byte array into another byte array by first doing base64 encoding
aoqi@0 660 * then encoding the result in ASCII.
aoqi@0 661 *
aoqi@0 662 * The caller must supply a big enough buffer.
aoqi@0 663 *
aoqi@0 664 * @return
aoqi@0 665 * the value of {@code ptr+((len+2)/3)*4}, which is the new offset
aoqi@0 666 * in the output buffer where the further bytes should be placed.
aoqi@0 667 */
aoqi@0 668 public static int _printBase64Binary(byte[] input, int offset, int len, byte[] out, int ptr) {
aoqi@0 669 byte[] buf = out;
aoqi@0 670 int remaining = len;
aoqi@0 671 int i;
aoqi@0 672 for (i=offset; remaining >= 3; remaining -= 3, i += 3 ) {
aoqi@0 673 buf[ptr++] = encodeByte(input[i]>>2);
aoqi@0 674 buf[ptr++] = encodeByte(
aoqi@0 675 ((input[i]&0x3)<<4) |
aoqi@0 676 ((input[i+1]>>4)&0xF));
aoqi@0 677 buf[ptr++] = encodeByte(
aoqi@0 678 ((input[i+1]&0xF)<<2)|
aoqi@0 679 ((input[i+2]>>6)&0x3));
aoqi@0 680 buf[ptr++] = encodeByte(input[i+2]&0x3F);
aoqi@0 681 }
aoqi@0 682 // encode when exactly 1 element (left) to encode
aoqi@0 683 if (remaining == 1) {
aoqi@0 684 buf[ptr++] = encodeByte(input[i]>>2);
aoqi@0 685 buf[ptr++] = encodeByte(((input[i])&0x3)<<4);
aoqi@0 686 buf[ptr++] = '=';
aoqi@0 687 buf[ptr++] = '=';
aoqi@0 688 }
aoqi@0 689 // encode when exactly 2 elements (left) to encode
aoqi@0 690 if (remaining == 2) {
aoqi@0 691 buf[ptr++] = encodeByte(input[i]>>2);
aoqi@0 692 buf[ptr++] = encodeByte(
aoqi@0 693 ((input[i]&0x3)<<4) |
aoqi@0 694 ((input[i+1]>>4)&0xF));
aoqi@0 695 buf[ptr++] = encodeByte((input[i+1]&0xF)<<2);
aoqi@0 696 buf[ptr++] = '=';
aoqi@0 697 }
aoqi@0 698
aoqi@0 699 return ptr;
aoqi@0 700 }
aoqi@0 701
aoqi@0 702 private static CharSequence removeOptionalPlus(CharSequence s) {
aoqi@0 703 int len = s.length();
aoqi@0 704
aoqi@0 705 if (len <= 1 || s.charAt(0) != '+') {
aoqi@0 706 return s;
aoqi@0 707 }
aoqi@0 708
aoqi@0 709 s = s.subSequence(1, len);
aoqi@0 710 char ch = s.charAt(0);
aoqi@0 711 if ('0' <= ch && ch <= '9') {
aoqi@0 712 return s;
aoqi@0 713 }
aoqi@0 714 if ('.' == ch) {
aoqi@0 715 return s;
aoqi@0 716 }
aoqi@0 717
aoqi@0 718 throw new NumberFormatException();
aoqi@0 719 }
aoqi@0 720
aoqi@0 721 private static boolean isDigitOrPeriodOrSign(char ch) {
aoqi@0 722 if ('0' <= ch && ch <= '9') {
aoqi@0 723 return true;
aoqi@0 724 }
aoqi@0 725 if (ch == '+' || ch == '-' || ch == '.') {
aoqi@0 726 return true;
aoqi@0 727 }
aoqi@0 728 return false;
aoqi@0 729 }
aoqi@0 730
aoqi@0 731 private static final Map<ClassLoader, DatatypeFactory> DF_CACHE = Collections.synchronizedMap(new WeakHashMap<ClassLoader, DatatypeFactory>());
aoqi@0 732
aoqi@0 733 public static DatatypeFactory getDatatypeFactory() {
aoqi@0 734 ClassLoader tccl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
aoqi@0 735 public ClassLoader run() {
aoqi@0 736 return Thread.currentThread().getContextClassLoader();
aoqi@0 737 }
aoqi@0 738 });
aoqi@0 739 DatatypeFactory df = DF_CACHE.get(tccl);
aoqi@0 740 if (df == null) {
aoqi@0 741 synchronized (DatatypeConverterImpl.class) {
aoqi@0 742 df = DF_CACHE.get(tccl);
aoqi@0 743 if (df == null) { // to prevent multiple initialization
aoqi@0 744 try {
aoqi@0 745 df = DatatypeFactory.newInstance();
aoqi@0 746 } catch (DatatypeConfigurationException e) {
aoqi@0 747 throw new Error(Messages.FAILED_TO_INITIALE_DATATYPE_FACTORY.format(),e);
aoqi@0 748 }
aoqi@0 749 DF_CACHE.put(tccl, df);
aoqi@0 750 }
aoqi@0 751 }
aoqi@0 752 }
aoqi@0 753 return df;
aoqi@0 754 }
aoqi@0 755
aoqi@0 756 private static final class CalendarFormatter {
aoqi@0 757
aoqi@0 758 public static String doFormat(String format, Calendar cal) throws IllegalArgumentException {
aoqi@0 759 int fidx = 0;
aoqi@0 760 int flen = format.length();
aoqi@0 761 StringBuilder buf = new StringBuilder();
aoqi@0 762
aoqi@0 763 while (fidx < flen) {
aoqi@0 764 char fch = format.charAt(fidx++);
aoqi@0 765
aoqi@0 766 if (fch != '%') { // not a meta character
aoqi@0 767 buf.append(fch);
aoqi@0 768 continue;
aoqi@0 769 }
aoqi@0 770
aoqi@0 771 // seen meta character. we don't do error check against the format
aoqi@0 772 switch (format.charAt(fidx++)) {
aoqi@0 773 case 'Y': // year
aoqi@0 774 formatYear(cal, buf);
aoqi@0 775 break;
aoqi@0 776
aoqi@0 777 case 'M': // month
aoqi@0 778 formatMonth(cal, buf);
aoqi@0 779 break;
aoqi@0 780
aoqi@0 781 case 'D': // days
aoqi@0 782 formatDays(cal, buf);
aoqi@0 783 break;
aoqi@0 784
aoqi@0 785 case 'h': // hours
aoqi@0 786 formatHours(cal, buf);
aoqi@0 787 break;
aoqi@0 788
aoqi@0 789 case 'm': // minutes
aoqi@0 790 formatMinutes(cal, buf);
aoqi@0 791 break;
aoqi@0 792
aoqi@0 793 case 's': // parse seconds.
aoqi@0 794 formatSeconds(cal, buf);
aoqi@0 795 break;
aoqi@0 796
aoqi@0 797 case 'z': // time zone
aoqi@0 798 formatTimeZone(cal, buf);
aoqi@0 799 break;
aoqi@0 800
aoqi@0 801 default:
aoqi@0 802 // illegal meta character. impossible.
aoqi@0 803 throw new InternalError();
aoqi@0 804 }
aoqi@0 805 }
aoqi@0 806
aoqi@0 807 return buf.toString();
aoqi@0 808 }
aoqi@0 809
aoqi@0 810 private static void formatYear(Calendar cal, StringBuilder buf) {
aoqi@0 811 int year = cal.get(Calendar.YEAR);
aoqi@0 812
aoqi@0 813 String s;
aoqi@0 814 if (year <= 0) // negative value
aoqi@0 815 {
aoqi@0 816 s = Integer.toString(1 - year);
aoqi@0 817 } else // positive value
aoqi@0 818 {
aoqi@0 819 s = Integer.toString(year);
aoqi@0 820 }
aoqi@0 821
aoqi@0 822 while (s.length() < 4) {
aoqi@0 823 s = '0' + s;
aoqi@0 824 }
aoqi@0 825 if (year <= 0) {
aoqi@0 826 s = '-' + s;
aoqi@0 827 }
aoqi@0 828
aoqi@0 829 buf.append(s);
aoqi@0 830 }
aoqi@0 831
aoqi@0 832 private static void formatMonth(Calendar cal, StringBuilder buf) {
aoqi@0 833 formatTwoDigits(cal.get(Calendar.MONTH) + 1, buf);
aoqi@0 834 }
aoqi@0 835
aoqi@0 836 private static void formatDays(Calendar cal, StringBuilder buf) {
aoqi@0 837 formatTwoDigits(cal.get(Calendar.DAY_OF_MONTH), buf);
aoqi@0 838 }
aoqi@0 839
aoqi@0 840 private static void formatHours(Calendar cal, StringBuilder buf) {
aoqi@0 841 formatTwoDigits(cal.get(Calendar.HOUR_OF_DAY), buf);
aoqi@0 842 }
aoqi@0 843
aoqi@0 844 private static void formatMinutes(Calendar cal, StringBuilder buf) {
aoqi@0 845 formatTwoDigits(cal.get(Calendar.MINUTE), buf);
aoqi@0 846 }
aoqi@0 847
aoqi@0 848 private static void formatSeconds(Calendar cal, StringBuilder buf) {
aoqi@0 849 formatTwoDigits(cal.get(Calendar.SECOND), buf);
aoqi@0 850 if (cal.isSet(Calendar.MILLISECOND)) { // milliseconds
aoqi@0 851 int n = cal.get(Calendar.MILLISECOND);
aoqi@0 852 if (n != 0) {
aoqi@0 853 String ms = Integer.toString(n);
aoqi@0 854 while (ms.length() < 3) {
aoqi@0 855 ms = '0' + ms; // left 0 paddings.
aoqi@0 856 }
aoqi@0 857 buf.append('.');
aoqi@0 858 buf.append(ms);
aoqi@0 859 }
aoqi@0 860 }
aoqi@0 861 }
aoqi@0 862
aoqi@0 863 /** formats time zone specifier. */
aoqi@0 864 private static void formatTimeZone(Calendar cal, StringBuilder buf) {
aoqi@0 865 TimeZone tz = cal.getTimeZone();
aoqi@0 866
aoqi@0 867 if (tz == null) {
aoqi@0 868 return;
aoqi@0 869 }
aoqi@0 870
aoqi@0 871 // otherwise print out normally.
aoqi@0 872 int offset = tz.getOffset(cal.getTime().getTime());
aoqi@0 873
aoqi@0 874 if (offset == 0) {
aoqi@0 875 buf.append('Z');
aoqi@0 876 return;
aoqi@0 877 }
aoqi@0 878
aoqi@0 879 if (offset >= 0) {
aoqi@0 880 buf.append('+');
aoqi@0 881 } else {
aoqi@0 882 buf.append('-');
aoqi@0 883 offset *= -1;
aoqi@0 884 }
aoqi@0 885
aoqi@0 886 offset /= 60 * 1000; // offset is in milli-seconds
aoqi@0 887
aoqi@0 888 formatTwoDigits(offset / 60, buf);
aoqi@0 889 buf.append(':');
aoqi@0 890 formatTwoDigits(offset % 60, buf);
aoqi@0 891 }
aoqi@0 892
aoqi@0 893 /** formats Integer into two-character-wide string. */
aoqi@0 894 private static void formatTwoDigits(int n, StringBuilder buf) {
aoqi@0 895 // n is always non-negative.
aoqi@0 896 if (n < 10) {
aoqi@0 897 buf.append('0');
aoqi@0 898 }
aoqi@0 899 buf.append(n);
aoqi@0 900 }
aoqi@0 901 }
aoqi@0 902
aoqi@0 903 // DEPRECATED METHODS, KEPT FOR JAXB1 GENERATED CLASSES COMPATIBILITY, WILL BE REMOVED IN FUTURE
aoqi@0 904
aoqi@0 905 @Deprecated
aoqi@0 906 public String parseString(String lexicalXSDString) {
aoqi@0 907 return lexicalXSDString;
aoqi@0 908 }
aoqi@0 909
aoqi@0 910 @Deprecated
aoqi@0 911 public BigInteger parseInteger(String lexicalXSDInteger) {
aoqi@0 912 return _parseInteger(lexicalXSDInteger);
aoqi@0 913 }
aoqi@0 914
aoqi@0 915 @Deprecated
aoqi@0 916 public String printInteger(BigInteger val) {
aoqi@0 917 return _printInteger(val);
aoqi@0 918 }
aoqi@0 919
aoqi@0 920 @Deprecated
aoqi@0 921 public int parseInt(String s) {
aoqi@0 922 return _parseInt(s);
aoqi@0 923 }
aoqi@0 924
aoqi@0 925 @Deprecated
aoqi@0 926 public long parseLong(String lexicalXSLong) {
aoqi@0 927 return _parseLong(lexicalXSLong);
aoqi@0 928 }
aoqi@0 929
aoqi@0 930 @Deprecated
aoqi@0 931 public short parseShort(String lexicalXSDShort) {
aoqi@0 932 return _parseShort(lexicalXSDShort);
aoqi@0 933 }
aoqi@0 934
aoqi@0 935 @Deprecated
aoqi@0 936 public String printShort(short val) {
aoqi@0 937 return _printShort(val);
aoqi@0 938 }
aoqi@0 939
aoqi@0 940 @Deprecated
aoqi@0 941 public BigDecimal parseDecimal(String content) {
aoqi@0 942 return _parseDecimal(content);
aoqi@0 943 }
aoqi@0 944
aoqi@0 945 @Deprecated
aoqi@0 946 public float parseFloat(String lexicalXSDFloat) {
aoqi@0 947 return _parseFloat(lexicalXSDFloat);
aoqi@0 948 }
aoqi@0 949
aoqi@0 950 @Deprecated
aoqi@0 951 public String printFloat(float v) {
aoqi@0 952 return _printFloat(v);
aoqi@0 953 }
aoqi@0 954
aoqi@0 955 @Deprecated
aoqi@0 956 public double parseDouble(String lexicalXSDDouble) {
aoqi@0 957 return _parseDouble(lexicalXSDDouble);
aoqi@0 958 }
aoqi@0 959
aoqi@0 960 @Deprecated
aoqi@0 961 public boolean parseBoolean(String lexicalXSDBoolean) {
aoqi@0 962 Boolean b = _parseBoolean(lexicalXSDBoolean);
aoqi@0 963 return (b == null) ? false : b.booleanValue();
aoqi@0 964 }
aoqi@0 965
aoqi@0 966 @Deprecated
aoqi@0 967 public String printBoolean(boolean val) {
aoqi@0 968 return val ? "true" : "false";
aoqi@0 969 }
aoqi@0 970
aoqi@0 971 @Deprecated
aoqi@0 972 public byte parseByte(String lexicalXSDByte) {
aoqi@0 973 return _parseByte(lexicalXSDByte);
aoqi@0 974 }
aoqi@0 975
aoqi@0 976 @Deprecated
aoqi@0 977 public String printByte(byte val) {
aoqi@0 978 return _printByte(val);
aoqi@0 979 }
aoqi@0 980
aoqi@0 981 @Deprecated
aoqi@0 982 public QName parseQName(String lexicalXSDQName, NamespaceContext nsc) {
aoqi@0 983 return _parseQName(lexicalXSDQName, nsc);
aoqi@0 984 }
aoqi@0 985
aoqi@0 986 @Deprecated
aoqi@0 987 public Calendar parseDateTime(String lexicalXSDDateTime) {
aoqi@0 988 return _parseDateTime(lexicalXSDDateTime);
aoqi@0 989 }
aoqi@0 990
aoqi@0 991 @Deprecated
aoqi@0 992 public String printDateTime(Calendar val) {
aoqi@0 993 return _printDateTime(val);
aoqi@0 994 }
aoqi@0 995
aoqi@0 996 @Deprecated
aoqi@0 997 public byte[] parseBase64Binary(String lexicalXSDBase64Binary) {
aoqi@0 998 return _parseBase64Binary(lexicalXSDBase64Binary);
aoqi@0 999 }
aoqi@0 1000
aoqi@0 1001 @Deprecated
aoqi@0 1002 public byte[] parseHexBinary(String s) {
aoqi@0 1003 final int len = s.length();
aoqi@0 1004
aoqi@0 1005 // "111" is not a valid hex encoding.
aoqi@0 1006 if (len % 2 != 0) {
aoqi@0 1007 throw new IllegalArgumentException("hexBinary needs to be even-length: " + s);
aoqi@0 1008 }
aoqi@0 1009
aoqi@0 1010 byte[] out = new byte[len / 2];
aoqi@0 1011
aoqi@0 1012 for (int i = 0; i < len; i += 2) {
aoqi@0 1013 int h = hexToBin(s.charAt(i));
aoqi@0 1014 int l = hexToBin(s.charAt(i + 1));
aoqi@0 1015 if (h == -1 || l == -1) {
aoqi@0 1016 throw new IllegalArgumentException("contains illegal character for hexBinary: " + s);
aoqi@0 1017 }
aoqi@0 1018
aoqi@0 1019 out[i / 2] = (byte) (h * 16 + l);
aoqi@0 1020 }
aoqi@0 1021
aoqi@0 1022 return out;
aoqi@0 1023 }
aoqi@0 1024
aoqi@0 1025 @Deprecated
aoqi@0 1026 private static int hexToBin(char ch) {
aoqi@0 1027 if ('0' <= ch && ch <= '9') {
aoqi@0 1028 return ch - '0';
aoqi@0 1029 }
aoqi@0 1030 if ('A' <= ch && ch <= 'F') {
aoqi@0 1031 return ch - 'A' + 10;
aoqi@0 1032 }
aoqi@0 1033 if ('a' <= ch && ch <= 'f') {
aoqi@0 1034 return ch - 'a' + 10;
aoqi@0 1035 }
aoqi@0 1036 return -1;
aoqi@0 1037 }
aoqi@0 1038
aoqi@0 1039 @Deprecated
aoqi@0 1040 private static final char[] hexCode = "0123456789ABCDEF".toCharArray();
aoqi@0 1041
aoqi@0 1042 @Deprecated
aoqi@0 1043 public String printHexBinary(byte[] data) {
aoqi@0 1044 StringBuilder r = new StringBuilder(data.length * 2);
aoqi@0 1045 for (byte b : data) {
aoqi@0 1046 r.append(hexCode[(b >> 4) & 0xF]);
aoqi@0 1047 r.append(hexCode[(b & 0xF)]);
aoqi@0 1048 }
aoqi@0 1049 return r.toString();
aoqi@0 1050 }
aoqi@0 1051
aoqi@0 1052 @Deprecated
aoqi@0 1053 public long parseUnsignedInt(String lexicalXSDUnsignedInt) {
aoqi@0 1054 return _parseLong(lexicalXSDUnsignedInt);
aoqi@0 1055 }
aoqi@0 1056
aoqi@0 1057 @Deprecated
aoqi@0 1058 public String printUnsignedInt(long val) {
aoqi@0 1059 return _printLong(val);
aoqi@0 1060 }
aoqi@0 1061
aoqi@0 1062 @Deprecated
aoqi@0 1063 public int parseUnsignedShort(String lexicalXSDUnsignedShort) {
aoqi@0 1064 return _parseInt(lexicalXSDUnsignedShort);
aoqi@0 1065 }
aoqi@0 1066
aoqi@0 1067 @Deprecated
aoqi@0 1068 public Calendar parseTime(String lexicalXSDTime) {
aoqi@0 1069 return getDatatypeFactory().newXMLGregorianCalendar(lexicalXSDTime).toGregorianCalendar();
aoqi@0 1070 }
aoqi@0 1071
aoqi@0 1072 @Deprecated
aoqi@0 1073 public String printTime(Calendar val) {
aoqi@0 1074 return CalendarFormatter.doFormat("%h:%m:%s%z", val);
aoqi@0 1075 }
aoqi@0 1076
aoqi@0 1077 @Deprecated
aoqi@0 1078 public Calendar parseDate(String lexicalXSDDate) {
aoqi@0 1079 return getDatatypeFactory().newXMLGregorianCalendar(lexicalXSDDate).toGregorianCalendar();
aoqi@0 1080 }
aoqi@0 1081
aoqi@0 1082 @Deprecated
aoqi@0 1083 public String printDate(Calendar val) {
aoqi@0 1084 return _printDate(val);
aoqi@0 1085 }
aoqi@0 1086
aoqi@0 1087 @Deprecated
aoqi@0 1088 public String parseAnySimpleType(String lexicalXSDAnySimpleType) {
aoqi@0 1089 return lexicalXSDAnySimpleType;
aoqi@0 1090 }
aoqi@0 1091
aoqi@0 1092 @Deprecated
aoqi@0 1093 public String printString(String val) {
aoqi@0 1094 return val;
aoqi@0 1095 }
aoqi@0 1096
aoqi@0 1097 @Deprecated
aoqi@0 1098 public String printInt(int val) {
aoqi@0 1099 return _printInt(val);
aoqi@0 1100 }
aoqi@0 1101
aoqi@0 1102 @Deprecated
aoqi@0 1103 public String printLong(long val) {
aoqi@0 1104 return _printLong(val);
aoqi@0 1105 }
aoqi@0 1106
aoqi@0 1107 @Deprecated
aoqi@0 1108 public String printDecimal(BigDecimal val) {
aoqi@0 1109 return _printDecimal(val);
aoqi@0 1110 }
aoqi@0 1111
aoqi@0 1112 @Deprecated
aoqi@0 1113 public String printDouble(double v) {
aoqi@0 1114 return _printDouble(v);
aoqi@0 1115 }
aoqi@0 1116
aoqi@0 1117 @Deprecated
aoqi@0 1118 public String printQName(QName val, NamespaceContext nsc) {
aoqi@0 1119 return _printQName(val, nsc);
aoqi@0 1120 }
aoqi@0 1121
aoqi@0 1122 @Deprecated
aoqi@0 1123 public String printBase64Binary(byte[] val) {
aoqi@0 1124 return _printBase64Binary(val);
aoqi@0 1125 }
aoqi@0 1126
aoqi@0 1127 @Deprecated
aoqi@0 1128 public String printUnsignedShort(int val) {
aoqi@0 1129 return String.valueOf(val);
aoqi@0 1130 }
aoqi@0 1131
aoqi@0 1132 @Deprecated
aoqi@0 1133 public String printAnySimpleType(String val) {
aoqi@0 1134 return val;
aoqi@0 1135 }
aoqi@0 1136
aoqi@0 1137 }

mercurial