@Override public void close() throws IOException { if (bitBufferLength > 0) { int charIndex = (bitBuffer << (alphabet.bitsPerChar - bitBufferLength)) & alphabet.mask; out.write(alphabet.encode(charIndex)); writtenChars++; if (paddingChar != null) { while (writtenChars % alphabet.charsPerChunk != 0) { out.write(paddingChar.charValue()); writtenChars++; } } } out.close(); } };
@Override public void write(int b) throws IOException { bitBuffer <<= 8; bitBuffer |= b & 0xFF; bitBufferLength += 8; while (bitBufferLength >= alphabet.bitsPerChar) { int charIndex = (bitBuffer >> (bitBufferLength - alphabet.bitsPerChar)) & alphabet.mask; out.write(alphabet.encode(charIndex)); writtenChars++; bitBufferLength -= alphabet.bitsPerChar; } }
void encodeChunkTo(Appendable target, byte[] bytes, int off, int len) throws IOException { checkNotNull(target); checkPositionIndexes(off, off + len, bytes.length); checkArgument(len <= alphabet.bytesPerChunk); long bitBuffer = 0; for (int i = 0; i < len; ++i) { bitBuffer |= bytes[off + i] & 0xFF; bitBuffer <<= 8; // Add additional zero byte in the end. } // Position of first character is length of bitBuffer minus bitsPerChar. final int bitOffset = (len + 1) * 8 - alphabet.bitsPerChar; int bitsProcessed = 0; while (bitsProcessed < len * 8) { int charIndex = (int) (bitBuffer >>> (bitOffset - bitsProcessed)) & alphabet.mask; target.append(alphabet.encode(charIndex)); bitsProcessed += alphabet.bitsPerChar; } if (paddingChar != null) { while (bitsProcessed < alphabet.bytesPerChunk * 8) { target.append(paddingChar.charValue()); bitsProcessed += alphabet.bitsPerChar; } } }
@Override void encodeTo(Appendable target, byte[] bytes, int off, int len) throws IOException { checkNotNull(target); checkPositionIndexes(off, off + len, bytes.length); int i = off; for (int remaining = len; remaining >= 3; remaining -= 3) { int chunk = (bytes[i++] & 0xFF) << 16 | (bytes[i++] & 0xFF) << 8 | bytes[i++] & 0xFF; target.append(alphabet.encode(chunk >>> 18)); target.append(alphabet.encode((chunk >>> 12) & 0x3F)); target.append(alphabet.encode((chunk >>> 6) & 0x3F)); target.append(alphabet.encode(chunk & 0x3F)); } if (i < off + len) { encodeChunkTo(target, bytes, i, off + len - i); } }