1 /* Jackson JSON-processor. 2 * 3 * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi 4 */ 5 package com.fasterxml.jackson.core; 6 7 /** 8 * Container for commonly used Base64 variants: 9 *<ul> 10 * <li> {@link #MIME} 11 * <li> {@link #MIME_NO_LINEFEEDS} 12 * <li> {@link #PEM} 13 * <li> {@link #MODIFIED_FOR_URL} 14 * </ul> 15 * 16 * @author Tatu Saloranta 17 */ 18 public final class Base64Variants 19 { 20 final static String STD_BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 21 22 /** 23 * This variant is what most people would think of "the standard" 24 * Base64 encoding. 25 *<p> 26 * See <a href="http://en.wikipedia.org/wiki/Base64">wikipedia Base64 entry</a> for details. 27 *<p> 28 * Note that although this can be thought of as the standard variant, 29 * it is <b>not</b> the default for Jackson: no-linefeeds alternative 30 * is because of JSON requirement of escaping all linefeeds. 31 */ 32 public final static Base64Variant MIME; 33 static { 34 MIME = new Base64Variant("MIME", STD_BASE64_ALPHABET, true, '=', 76); 35 } 36 37 /** 38 * Slightly non-standard modification of {@link #MIME} which does not 39 * use linefeeds (max line length set to infinite). Useful when linefeeds 40 * wouldn't work well (possibly in attributes), or for minor space savings 41 * (save 1 linefeed per 76 data chars, ie. ~1.4% savings). 42 */ 43 public final static Base64Variant MIME_NO_LINEFEEDS; 44 static { 45 MIME_NO_LINEFEEDS = new Base64Variant(MIME, "MIME-NO-LINEFEEDS", Integer.MAX_VALUE); 46 } 47 48 /** 49 * This variant is the one that predates {@link #MIME}: it is otherwise 50 * identical, except that it mandates shorter line length. 51 */ 52 public final static Base64Variant PEM = new Base64Variant(MIME, "PEM", true, '=', 64); 53 54 /** 55 * This non-standard variant is usually used when encoded data needs to be 56 * passed via URLs (such as part of GET request). It differs from the 57 * base {@link #MIME} variant in multiple ways. 58 * First, no padding is used: this also means that it generally can not 59 * be written in multiple separate but adjacent chunks (which would not 60 * be the usual use case in any case). Also, no linefeeds are used (max 61 * line length set to infinite). And finally, two characters (plus and 62 * slash) that would need quoting in URLs are replaced with more 63 * optimal alternatives (hyphen and underscore, respectively). 64 */ 65 public final static Base64Variant MODIFIED_FOR_URL; 66 static { 67 StringBuilder sb = new StringBuilder(STD_BASE64_ALPHABET); 68 // Replace plus with hyphen, slash with underscore (and no padding) 69 sb.setCharAt(sb.indexOf("+"), '-'); 70 sb.setCharAt(sb.indexOf("/"), '_'); 71 // And finally, let's not split lines either, wouldn't work too well with URLs 72 MODIFIED_FOR_URL = new Base64Variant("MODIFIED-FOR-URL", sb.toString(), false, Base64Variant.PADDING_CHAR_NONE, Integer.MAX_VALUE); 73 } 74 75 /** 76 * Method used to get the default variant ("MIME_NO_LINEFEEDS") for cases 77 * where caller does not explicitly specify the variant. 78 * We will prefer no-linefeed version because linefeeds in JSON values 79 * must be escaped, making linefeed-containing variants sub-optimal. 80 */ getDefaultVariant()81 public static Base64Variant getDefaultVariant() { 82 return MIME_NO_LINEFEEDS; 83 } 84 85 /** 86 * @since 2.1 87 */ valueOf(String name)88 public static Base64Variant valueOf(String name) throws IllegalArgumentException 89 { 90 if (MIME._name.equals(name)) { 91 return MIME; 92 } 93 if (MIME_NO_LINEFEEDS._name.equals(name)) { 94 return MIME_NO_LINEFEEDS; 95 } 96 if (PEM._name.equals(name)) { 97 return PEM; 98 } 99 if (MODIFIED_FOR_URL._name.equals(name)) { 100 return MODIFIED_FOR_URL; 101 } 102 if (name == null) { 103 name = "<null>"; 104 } else { 105 name = "'"+name+"'"; 106 } 107 throw new IllegalArgumentException("No Base64Variant with name "+name); 108 } 109 } 110