
org.krysalis.barcode4j.tools.Base64InputStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of barcode4j-light Show documentation
Show all versions of barcode4j-light Show documentation
Barcode4J is a flexible generator for barcodes written in Java.
The newest version!
/*
* Copyright 2008 Jeremias Maerki.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id: Base64InputStream.java,v 1.1 2008-09-15 07:10:28 jmaerki Exp $ */
package org.krysalis.barcode4j.tools;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Arrays;
/**
* Base64-implementation as an {@code InputStream} reading Base64-encoded data
* from a {@code Reader}.
*/
public class Base64InputStream extends InputStream {
private static final int EOF = -1;
private static final byte[] LOOKUP = new byte[128];
static {
Arrays.fill(LOOKUP, (byte) -1);
int idx = 0;
for (char ch = 'A'; ch <= 'Z'; ch++) {
LOOKUP[ch] = (byte) idx++;
}
for (char ch = 'a'; ch <= 'z'; ch++) {
LOOKUP[ch] = (byte) idx++;
}
for (char ch = '0'; ch <= '9'; ch++) {
LOOKUP[ch] = (byte) idx++;
}
LOOKUP['-'] = (byte) idx; //URL- & filename-safe
LOOKUP['+'] = (byte) idx++;
LOOKUP['_'] = (byte) idx; //URL- & filename-safe
LOOKUP['/'] = (byte) idx++;
}
private Reader source;
private final char[] quadBuffer = new char[4];
private final byte[] triple = new byte[3];
private int tripleIndex = 4;
private int tripleFilled;
/**
* Constructs a new instance.
*
* @param source the Reader to read the Base64-encoded data from
*/
public Base64InputStream(Reader source) {
if (source == null) {
throw new NullPointerException("source must not be null");
}
this.source = source;
}
/**
* {@inheritDoc}
*/
public int read() throws IOException {
checkOpen();
if (tripleIndex >= tripleFilled) {
if (!readNextTriple()) {
return EOF;
}
}
return triple[tripleIndex++];
}
/**
* {@inheritDoc}
*/
public void close() throws IOException {
this.source.close();
this.source = null;
}
private boolean readNextTriple() throws IOException {
int offset = 0;
while (offset < 4) {
int ch = source.read();
if (ch < 0) {
return false;
}
else if (ch == '\r' || ch == '\n' || ch == ' ') {
continue;
}
quadBuffer[offset++] = (char) ch;
}
int quad = 0;
tripleFilled = 3;
for (int i = 0; i < 4; i++) {
byte b = -1;
char ch = quadBuffer[i];
if ('=' == ch) {
if (i < 2) {
throw new IOException("Padding character at invalid position");
}
else {
tripleFilled = Math.min(i - 1, tripleFilled);
break;
}
}
if (ch < 128) {
b = LOOKUP[ch];
}
if (b < 0) {
throw new IOException("Illegal Base64 character encountered: " + ch);
}
quad |= b << ((3 - i) * 6);
}
triple[0] = (byte) ((quad & 0xFF0000) >> 16);
triple[1] = (byte) ((quad & 0xFF00) >> 8);
triple[2] = (byte) (quad & 0xFF);
tripleIndex = 0;
return true;
}
private void checkOpen() throws IOException {
if (this.source == null) {
throw new IOException("Stream is already closed");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy