static CharInput ignoringInput(final CharInput delegate, final CharMatcher toIgnore) { checkNotNull(delegate); checkNotNull(toIgnore); return new CharInput() { @Override public int read() throws IOException { int readChar; do { readChar = delegate.read(); } while (readChar != -1 && toIgnore.matches((char) readChar)); return readChar; } @Override public void close() throws IOException { delegate.close(); } }; }
@Override ByteInput decodingStream(final CharInput reader) { checkNotNull(reader); return new ByteInput() { int bitBuffer = 0; int bitBufferLength = 0; int readChars = 0; boolean hitPadding = false; final CharMatcher paddingMatcher = padding(); @Override public int read() throws IOException { while (true) { int readChar = reader.read(); if (readChar == -1) { if (!hitPadding && !alphabet.isValidPaddingStartPosition(readChars)) { throw new DecodingException("Invalid input length " + readChars); } return -1; } readChars++; char ch = (char) readChar; if (paddingMatcher.matches(ch)) { if (!hitPadding && (readChars == 1 || !alphabet.isValidPaddingStartPosition(readChars - 1))) { throw new DecodingException("Padding cannot start at index " + readChars); } hitPadding = true; } else if (hitPadding) { throw new DecodingException( "Expected padding character but found '" + ch + "' at index " + readChars); } else { bitBuffer <<= alphabet.bitsPerChar; bitBuffer |= alphabet.decode(ch); bitBufferLength += alphabet.bitsPerChar; if (bitBufferLength >= 8) { bitBufferLength -= 8; return (bitBuffer >> bitBufferLength) & 0xFF; } } } } @Override public void close() throws IOException { reader.close(); } }; }
@Override ByteInput decodingStream(final CharInput input) { return delegate.decodingStream(ignoringInput(input, separatorChars)); }
@Override ByteInput decodingStream(final CharInput reader) { checkNotNull(reader); return new ByteInput() { int bitBuffer = 0; int bitBufferLength = 0; int readChars = 0; boolean hitPadding = false; final CharMatcher paddingMatcher = padding(); @Override public int read() throws IOException { while (true) { int readChar = reader.read(); if (readChar == -1) { if (!hitPadding && !alphabet.isValidPaddingStartPosition(readChars)) { throw new IOException("Invalid input length " + readChars); } return -1; } readChars++; char ch = (char) readChar; if (paddingMatcher.matches(ch)) { if (!hitPadding && (readChars == 1 || !alphabet.isValidPaddingStartPosition(readChars - 1))) { throw new IOException("Padding cannot start at index " + readChars); } hitPadding = true; } else if (hitPadding) { throw new IOException( "Expected padding character but found '" + ch + "' at index " + readChars); } else { bitBuffer <<= alphabet.bitsPerChar; bitBuffer |= alphabet.decode(ch); bitBufferLength += alphabet.bitsPerChar; if (bitBufferLength >= 8) { bitBufferLength -= 8; return (bitBuffer >> bitBufferLength) & 0xFF; } } } } @Override public void close() throws IOException { reader.close(); } }; }
abstract ByteInput decodingStream(CharInput charInput);