1 package com.thaiopensource.datatype.xsd; 2 3 import org.relaxng.datatype.ValidationContext; 4 5 class Base64BinaryDatatype extends BinaryDatatype { 6 static private final byte[] weightTable = makeWeightTable(); 7 static private final byte INVALID = (byte)-1; 8 static private final byte WHITESPACE = (byte)-2; 9 static private final byte PADDING = (byte)-3; 10 11 boolean lexicallyAllows(String str) { 13 return byteCount(str) >= 0; 14 } 15 16 private static int byteCount(String str) { 17 int nChars = 0; 18 int nPadding = 0; 19 int lastCharWeight = -1; 20 for (int i = 0, len = str.length(); i < len; i++) { 21 char c = str.charAt(i); 22 if (c >= 128) 23 return -1; 24 int w = weightTable[c]; 25 switch (w) { 26 case WHITESPACE: 27 break; 28 case PADDING: 29 if (++nPadding > 2) 30 return -1; 31 break; 32 case INVALID: 33 return -1; 34 default: 35 if (nPadding > 0) 36 return -1; 37 lastCharWeight = w; 38 nChars++; 39 break; 40 } 41 } 42 if (((nChars + nPadding) & 0x3) != 0) 43 return -1; 44 switch (nPadding) { 45 case 1: 46 if ((lastCharWeight & 0x3) != 0) 49 return -1; 50 break; 51 case 2: 52 if ((lastCharWeight & 0xF) != 0) 55 return -1; 56 break; 57 } 58 return ((nChars + nPadding) >> 2)*3 - nPadding; 59 } 60 61 Object getValue(String str, ValidationContext vc) { 62 int nBytes = byteCount(str); 63 byte[] value = new byte[nBytes]; 64 int valueIndex = 0; 65 int nBytesAccum = 0; 66 int accum = 0; 67 for (int i = 0, len = str.length(); i < len; i++) { 68 int w = weightTable[str.charAt(i)]; 69 if (w != WHITESPACE) { 70 accum <<= 6; 71 if (w != PADDING) 72 accum |= w; 73 if (++nBytesAccum == 4) { 74 for (int shift = 16; shift >= 0; shift -= 8) { 75 if (valueIndex < nBytes) 76 value[valueIndex++] = (byte)((accum >> shift) & 0xFF); 77 } 78 nBytesAccum = 0; 79 accum = 0; 80 } 81 } 82 } 83 return value; 84 } 85 86 static private byte[] makeWeightTable() { 87 byte[] w = new byte[128]; 88 byte n = INVALID; 89 for (int i = 0; i < 128; i++) 90 w[i] = n; 91 n = 0; 92 for (int i = 'A'; i <= 'Z'; i++, n++) 93 w[i] = n; 94 for (int i = 'a'; i <= 'z'; i++, n++) 95 w[i] = n; 96 for (int i = '0'; i <= '9'; i++, n++) 97 w[i] = n; 98 w['+'] = n++; 99 w['/'] = n++; 100 w[' '] = w['\t'] = w['\r'] = w['\n'] = WHITESPACE; 101 w['='] = PADDING; 102 return w; 103 } 104 105 } 106 | Popular Tags |