@Override protected byte[] doEncoding(byte[] bytes) { if (bytes == null) { return null; } byte[] data = QuotedPrintableCodec.encodeQuotedPrintable(PRINTABLE_CHARS, bytes); if (this.encodeBlanks) { for (int i = 0; i < data.length; i++) { if (data[i] == BLANK) { data[i] = UNDERSCORE; } } } return data; }
/** * Encodes an array of bytes into an array of quoted-printable 7-bit characters. Unsafe characters * are escaped. * * <p>This function implements a subset of quoted-printable encoding specification (rule #1 and * rule #2) as defined in RFC 1521 and is suitable for encoding binary data and unformatted text. * * @param printable bitset of characters deemed quoted-printable * @param bytes array of bytes to be encoded * @return array of bytes containing quoted-printable data */ public static final byte[] encodeQuotedPrintable(BitSet printable, byte[] bytes) { if (bytes == null) { return null; } if (printable == null) { printable = PRINTABLE_CHARS; } ByteArrayOutputStream buffer = new ByteArrayOutputStream(); for (int i = 0; i < bytes.length; i++) { int b = bytes[i]; if (b < 0) { b = 256 + b; } if (printable.get(b)) { buffer.write(b); } else { encodeQuotedPrintable(b, buffer); } } return buffer.toByteArray(); }
/** * Encodes an array of bytes into an array of quoted-printable 7-bit characters. Unsafe characters * are escaped. * * <p>Depending on the selection of the {@code strict} parameter, this function either implements * the full ruleset or only a subset of quoted-printable encoding specification (rule #1 and rule * #2) as defined in RFC 1521 and is suitable for encoding binary data and unformatted text. * * @param printable bitset of characters deemed quoted-printable * @param bytes array of bytes to be encoded * @param strict if {@code true} the full ruleset is used, otherwise only rule #1 and rule #2 * @return array of bytes containing quoted-printable data * @since 1.10 */ public static final byte[] encodeQuotedPrintable( BitSet printable, final byte[] bytes, boolean strict) { if (bytes == null) { return null; } if (printable == null) { printable = PRINTABLE_CHARS; } final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); if (strict) { int pos = 1; // encode up to buffer.length - 3, the last three octets will be treated // separately for simplification of note #3 for (int i = 0; i < bytes.length - 3; i++) { int b = getUnsignedOctet(i, bytes); if (pos < SAFE_LENGTH) { // up to this length it is safe to add any byte, encoded or not pos += encodeByte(b, !printable.get(b), buffer); } else { // rule #3: whitespace at the end of a line *must* be encoded encodeByte(b, !printable.get(b) || isWhitespace(b), buffer); // rule #5: soft line break buffer.write(ESCAPE_CHAR); buffer.write(CR); buffer.write(LF); pos = 1; } } // rule #3: whitespace at the end of a line *must* be encoded // if we would do a soft break line after this octet, encode whitespace int b = getUnsignedOctet(bytes.length - 3, bytes); boolean encode = !printable.get(b) || (isWhitespace(b) && pos > SAFE_LENGTH - 5); pos += encodeByte(b, encode, buffer); // note #3: '=' *must not* be the ultimate or penultimate character // simplification: if < 6 bytes left, do a soft line break as we may need // exactly 6 bytes space for the last 2 bytes if (pos > SAFE_LENGTH - 2) { buffer.write(ESCAPE_CHAR); buffer.write(CR); buffer.write(LF); } for (int i = bytes.length - 2; i < bytes.length; i++) { b = getUnsignedOctet(i, bytes); // rule #3: trailing whitespace shall be encoded encode = !printable.get(b) || (i > bytes.length - 2 && isWhitespace(b)); encodeByte(b, encode, buffer); } } else { for (final byte c : bytes) { int b = c; if (b < 0) { b = 256 + b; } if (printable.get(b)) { buffer.write(b); } else { encodeQuotedPrintable(b, buffer); } } } return buffer.toByteArray(); }