@@ -88,7 +88,7 @@ public final class Base64Variant
8888 private final transient boolean _usesPadding ;
8989
9090 /**
91- * Characted used for padding, if any ({@link #PADDING_CHAR_NONE} if not).
91+ * Character used for padding, if any ({@link #PADDING_CHAR_NONE} if not).
9292 */
9393 private final transient char _paddingChar ;
9494
@@ -367,21 +367,17 @@ public String encode(byte[] input)
367367
368368 /**
369369 * Convenience method for converting given byte array as base64 encoded String
370- * using this variant's settings,
371- * optionally enclosed in double-quotes.
370+ * using this variant's settings, optionally enclosed in double-quotes.
371+ * Linefeeds added, if needed, are expressed as 2-character JSON (and Java source)
372+ * escape sequence of backslash + `n`.
372373 *
373374 * @param input Byte array to encode
374375 * @param addQuotes Whether to surround resulting value in double quotes or not
375376 */
376377 public String encode (byte [] input , boolean addQuotes )
377378 {
378- int inputEnd = input .length ;
379- StringBuilder sb ;
380- {
381- // let's approximate... 33% overhead, ~= 3/8 (0.375)
382- int outputLen = inputEnd + (inputEnd >> 2 ) + (inputEnd >> 3 );
383- sb = new StringBuilder (outputLen );
384- }
379+ final int inputEnd = input .length ;
380+ final StringBuilder sb = new StringBuilder (inputEnd + (inputEnd >> 2 ) + (inputEnd >> 3 ));
385381 if (addQuotes ) {
386382 sb .append ('"' );
387383 }
@@ -422,13 +418,61 @@ public String encode(byte[] input, boolean addQuotes)
422418 return sb .toString ();
423419 }
424420
421+ /**
422+ * Convenience method for converting given byte array as base64 encoded String
423+ * using this variant's settings, optionally enclosed in double-quotes.
424+ * Linefeed character to use is passed explicitly.
425+ *
426+ * @param input Byte array to encode
427+ * @param addQuotes Whether to surround resulting value in double quotes or not
428+ *
429+ * @since 2.10
430+ */
431+ public String encode (byte [] input , boolean addQuotes , String linefeed )
432+ {
433+ final int inputEnd = input .length ;
434+ final StringBuilder sb = new StringBuilder (inputEnd + (inputEnd >> 2 ) + (inputEnd >> 3 ));
435+ if (addQuotes ) {
436+ sb .append ('"' );
437+ }
438+
439+ int chunksBeforeLF = getMaxLineLength () >> 2 ;
440+
441+ int inputPtr = 0 ;
442+ int safeInputEnd = inputEnd -3 ;
443+
444+ while (inputPtr <= safeInputEnd ) {
445+ int b24 = ((int ) input [inputPtr ++]) << 8 ;
446+ b24 |= ((int ) input [inputPtr ++]) & 0xFF ;
447+ b24 = (b24 << 8 ) | (((int ) input [inputPtr ++]) & 0xFF );
448+ encodeBase64Chunk (sb , b24 );
449+ if (--chunksBeforeLF <= 0 ) {
450+ sb .append (linefeed );
451+ chunksBeforeLF = getMaxLineLength () >> 2 ;
452+ }
453+ }
454+ int inputLeft = inputEnd - inputPtr ;
455+ if (inputLeft > 0 ) {
456+ int b24 = ((int ) input [inputPtr ++]) << 16 ;
457+ if (inputLeft == 2 ) {
458+ b24 |= (((int ) input [inputPtr ++]) & 0xFF ) << 8 ;
459+ }
460+ encodeBase64Partial (sb , b24 , inputLeft );
461+ }
462+
463+ if (addQuotes ) {
464+ sb .append ('"' );
465+ }
466+ return sb .toString ();
467+ }
468+
425469 /**
426470 * Convenience method for decoding contents of a Base64-encoded String,
427471 * using this variant's settings.
428- *
472+ *
429473 * @param input
430- *
431- * @since 2.2. 3
474+ *
475+ * @since 2.3
432476 *
433477 * @throws IllegalArgumentException if input is not valid base64 encoded data
434478 */
0 commit comments