diff options
Diffstat (limited to 'mocca-1.2.11/smcc/src/main/java/at/gv/egiz/smcc/util')
4 files changed, 0 insertions, 916 deletions
diff --git a/mocca-1.2.11/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java b/mocca-1.2.11/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java deleted file mode 100644 index fcd0b876..00000000 --- a/mocca-1.2.11/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java +++ /dev/null @@ -1,368 +0,0 @@ -/* -* Copyright 2008 Federal Chancellery Austria and -* Graz University of Technology -* -* 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. -*/ -package at.gv.egiz.smcc.util; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.CharBuffer; -import java.nio.charset.Charset; - -import javax.smartcardio.CardChannel; -import javax.smartcardio.CardException; -import javax.smartcardio.CommandAPDU; -import javax.smartcardio.ResponseAPDU; - -import at.gv.egiz.smcc.ChangeReferenceDataAPDUSpec; -import at.gv.egiz.smcc.NewReferenceDataAPDUSpec; -import at.gv.egiz.smcc.SecurityStatusNotSatisfiedException; -import at.gv.egiz.smcc.SignatureCardException; -import at.gv.egiz.smcc.VerifyAPDUSpec; - -public class ISO7816Utils { - - public static TransparentFileInputStream openTransparentFileInputStream( - final CardChannel channel, int maxSize) { - - TransparentFileInputStream file = new TransparentFileInputStream(maxSize) { - - @Override - protected byte[] readBinary(int offset, int len) throws IOException { - - ResponseAPDU resp; - try { - resp = channel.transmit(new CommandAPDU(0x00, 0xB0, - 0x7F & (offset >> 8), offset & 0xFF, len)); - } catch (CardException e) { - throw new IOException(e); - } - - Throwable cause; - if (resp.getSW() == 0x9000) { - return resp.getData(); - } else if (resp.getSW() == 0x6982) { - cause = new SecurityStatusNotSatisfiedException(); - } else { - cause = new SignatureCardException("Failed to read bytes (offset=" + offset + ",len=" - + len + ") SW=" + Integer.toHexString(resp.getSW()) + "."); - } - throw new IOException(cause); - - } - - }; - - return file; - - } - - public static byte[] readTransparentFile(CardChannel channel, int maxSize) - throws CardException, SignatureCardException { - - TransparentFileInputStream is = openTransparentFileInputStream(channel, maxSize); - - try { - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - int len; - for (byte[] b = new byte[256]; (len = is.read(b)) != -1;) { - os.write(b, 0, len); - } - - return os.toByteArray(); - - } catch (IOException e) { - Throwable cause = e.getCause(); - if (cause instanceof CardException) { - throw (CardException) cause; - } - if (cause instanceof SignatureCardException) { - throw (SignatureCardException) cause; - } - throw new SignatureCardException(e); - } - - } - - public static byte[] readTransparentFileTLV(CardChannel channel, int maxSize, - byte expectedType) throws CardException, SignatureCardException { - - TransparentFileInputStream is = openTransparentFileInputStream(channel, - maxSize); - - return readTransparentFileTLV(is, maxSize, expectedType); - - } - - public static byte[] readTransparentFileTLV(TransparentFileInputStream is, int maxSize, - byte expectedType) throws CardException, SignatureCardException { - - - try { - - is.mark(256); - - // check expected type - int b = is.read(); - if (b == 0x00) { - return null; - } - if (b == -1 || expectedType != (0xFF & b)) { - throw new SignatureCardException("Unexpected TLV type. Expected " - + Integer.toHexString(expectedType) + " but was " - + Integer.toHexString(b) + "."); - } - - // get actual length - int actualSize = 2; - b = is.read(); - if (b == -1) { - return null; - } else if ((0x80 & b) > 0) { - int octets = (0x0F & b); - actualSize += octets; - for (int i = 1; i <= octets; i++) { - b = is.read(); - if (b == -1) { - return null; - } - actualSize += (0xFF & b) << ((octets - i) * 8); - } - } else { - actualSize += 0xFF & b; - } - - // set limit to actual size and read into buffer - is.reset(); - is.setLimit(actualSize); - byte[] buf = new byte[actualSize]; - if (is.read(buf) == actualSize) { - return buf; - } else { - return null; - } - - } catch (IOException e) { - Throwable cause = e.getCause(); - if (cause instanceof CardException) { - throw (CardException) cause; - } - if (cause instanceof SignatureCardException) { - throw (SignatureCardException) cause; - } - throw new SignatureCardException(e); - } - - } - - public static int getLengthFromFCx(byte[] fcx) { - - int len = -1; - - if (fcx.length != 0 && (fcx[0] == (byte) 0x62 || fcx[0] == (byte) 0x6F)) { - int pos = 2; - while (pos < (fcx[1] - 2)) { - switch (fcx[pos]) { - - case (byte) 0x80: - case (byte) 0x81: { - len = 0xFF & fcx[pos + 2]; - for (int i = 1; i < fcx[pos + 1]; i++) { - len<<=8; - len+=0xFF & fcx[pos + i + 2]; - } - } - - default: - pos += 0xFF & fcx[pos + 1] + 2; - } - } - } - - return len; - - } - - public static byte[] readRecord(CardChannel channel, int record) throws CardException, SignatureCardException { - - ResponseAPDU resp = channel.transmit( - new CommandAPDU(0x00, 0xB2, record, 0x04, 256)); - if (resp.getSW() == 0x9000) { - return resp.getData(); - } else { - throw new SignatureCardException("Failed to read records. SW=" - + Integer.toHexString(resp.getSW())); - } - - } - - public static void formatPIN(int pinFormat, int pinJustification, byte[] fpin, byte[] mask, char[] pin) { - - boolean left = (pinJustification == VerifyAPDUSpec.PIN_JUSTIFICATION_LEFT); - - int j = (left) ? 0 : fpin.length - 1; - int step = (left) ? 1 : - 1; - switch (pinFormat) { - case VerifyAPDUSpec.PIN_FORMAT_BINARY: - if (fpin.length < pin.length) { - throw new IllegalArgumentException(); - } - for (int i = 0; i < pin.length; i++) { - fpin[j] = (byte) Character.digit(pin[i], 10); - mask[j] = (byte) 0xFF; - j += step; - } - break; - - case VerifyAPDUSpec.PIN_FORMAT_BCD: - if (fpin.length * 2 < pin.length) { - throw new IllegalArgumentException(); - } - for (int i = 0; i < pin.length; i++) { - int digit = Character.digit(pin[i], 10); - boolean h = (i % 2 == 0) ^ left; - fpin[j] |= h ? digit : digit << 4 ; - mask[j] |= h ? (byte) 0x0F : (byte) 0xF0; - j += (i % 2) * step; - } - break; - - case VerifyAPDUSpec.PIN_FORMAT_ASCII: - if (fpin.length < pin.length) { - throw new IllegalArgumentException(); - } - byte[] asciiPin = Charset.forName("ASCII").encode(CharBuffer.wrap(pin)).array(); - for (int i = 0; i < pin.length; i++) { - fpin[j] = asciiPin[i]; - mask[j] = (byte) 0xFF; - j += step; - } - break; - } - - } - - public static void insertPIN(byte[] apdu, int pos, byte[] fpin, byte[] mask) { - for (int i = 0; i < fpin.length; i++) { - apdu[pos + i] &= ~mask[i]; - apdu[pos + i] |= fpin[i]; - } - } - - public static void insertPINLength(byte[] apdu, int length, int lengthSize, int pos, int offset) { - - // use short (2 byte) to be able to shift the pin length - // by the number of bits given by the pin length position - short size = (short) (0x00FF & length); - short sMask = (short) ((1 << lengthSize) - 1); - // shift to the proper position - int shift = 16 - lengthSize - (pos % 8); - offset += (pos / 8) + 5; - size <<= shift; - sMask <<= shift; - // insert upper byte - apdu[offset] &= (0xFF & (~sMask >> 8)); - apdu[offset] |= (0xFF & (size >> 8)); - // insert lower byte - apdu[offset + 1] &= (0xFF & ~sMask); - apdu[offset + 1] |= (0xFF & size); - - } - - public static CommandAPDU createVerifyAPDU(VerifyAPDUSpec apduSpec, char[] pin) { - - // format pin - byte[] fpin = new byte[apduSpec.getPinLength()]; - byte[] mask = new byte[apduSpec.getPinLength()]; - formatPIN(apduSpec.getPinFormat(), apduSpec.getPinJustification(), fpin, mask, pin); - - byte[] apdu = apduSpec.getApdu(); - - // insert formated pin - insertPIN(apdu, apduSpec.getPinPosition() + 5, fpin, mask); - - // insert pin length - if (apduSpec.getPinLengthSize() != 0) { - insertPINLength(apdu, pin.length, apduSpec.getPinLengthSize(), apduSpec.getPinLengthPos(), 0); - } - - return new CommandAPDU(apdu); - - } - - public static CommandAPDU createChangeReferenceDataAPDU( - ChangeReferenceDataAPDUSpec apduSpec, char[] oldPin, char[] newPin) { - - // format old pin - byte[] fpin = new byte[apduSpec.getPinLength()]; - byte[] mask = new byte[apduSpec.getPinLength()]; - formatPIN(apduSpec.getPinFormat(), apduSpec.getPinJustification(), fpin, mask, oldPin); - - byte[] apdu = apduSpec.getApdu(); - - // insert formated old pin - insertPIN(apdu, apduSpec.getPinPosition() + apduSpec.getPinInsertionOffsetOld() + 5, fpin, mask); - - // insert pin length - if (apduSpec.getPinLengthSize() != 0) { - insertPINLength(apdu, oldPin.length, apduSpec.getPinLengthSize(), - apduSpec.getPinLengthPos(), apduSpec.getPinInsertionOffsetOld()); - } - - // format new pin - fpin = new byte[apduSpec.getPinLength()]; - mask = new byte[apduSpec.getPinLength()]; - formatPIN(apduSpec.getPinFormat(), apduSpec.getPinJustification(), fpin, mask, newPin); - - // insert formated new pin - insertPIN(apdu, apduSpec.getPinPosition() + apduSpec.getPinInsertionOffsetNew() + 5, fpin, mask); - - // insert pin length - if (apduSpec.getPinLengthSize() != 0) { - insertPINLength(apdu, newPin.length, apduSpec.getPinLengthSize(), - apduSpec.getPinLengthPos(), apduSpec.getPinInsertionOffsetNew()); - } - - return new CommandAPDU(apdu); - - } - - public static CommandAPDU createNewReferenceDataAPDU( - NewReferenceDataAPDUSpec apduSpec, char[] newPin) { - - // format old pin - byte[] fpin = new byte[apduSpec.getPinLength()]; - byte[] mask = new byte[apduSpec.getPinLength()]; - formatPIN(apduSpec.getPinFormat(), apduSpec.getPinJustification(), fpin, mask, newPin); - - byte[] apdu = apduSpec.getApdu(); - - // insert formated new pin - insertPIN(apdu, apduSpec.getPinPosition() + apduSpec.getPinInsertionOffsetNew() + 5, fpin, mask); - - // insert pin length - if (apduSpec.getPinLengthSize() != 0) { - insertPINLength(apdu, newPin.length, apduSpec.getPinLengthSize(), - apduSpec.getPinLengthPos(), apduSpec.getPinInsertionOffsetNew()); - } - - return new CommandAPDU(apdu); - - } - - -} diff --git a/mocca-1.2.11/smcc/src/main/java/at/gv/egiz/smcc/util/SMCCHelper.java b/mocca-1.2.11/smcc/src/main/java/at/gv/egiz/smcc/util/SMCCHelper.java deleted file mode 100644 index f7d3bab7..00000000 --- a/mocca-1.2.11/smcc/src/main/java/at/gv/egiz/smcc/util/SMCCHelper.java +++ /dev/null @@ -1,150 +0,0 @@ -/* -* Copyright 2008 Federal Chancellery Austria and -* Graz University of Technology -* -* 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. -*/ -package at.gv.egiz.smcc.util;
-
-import java.util.Locale;
-import java.util.Map;
-
-import javax.smartcardio.ATR;
-import javax.smartcardio.Card;
-import javax.smartcardio.CardTerminal;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.smcc.CardNotSupportedException;
-import at.gv.egiz.smcc.SignatureCard;
-import at.gv.egiz.smcc.SignatureCardFactory;
-
-public class SMCCHelper {
-
- public final static int NO_CARD = 0;
- public final static int PC_SC_NOT_SUPPORTED = 1;
- public final static int TERMINAL_NOT_PRESENT = 2;
- public final static int CARD_NOT_SUPPORTED = 3;
- public final static int CARD_FOUND = 4;
-
- private final static Log log = LogFactory.getLog(SMCCHelper.class);
-
- protected SmartCardIO smartCardIO = new SmartCardIO();
- protected int resultCode = NO_CARD;
- protected SignatureCard signatureCard = null;
- protected static boolean useSWCard = false;
-
- public SMCCHelper() {
- update();
- }
-
- public synchronized void update() {
- update(-1);
- }
-
- public synchronized void update(int sleep) {
- SignatureCardFactory factory = SignatureCardFactory.getInstance();
- if (useSWCard) {
- try {
- signatureCard = factory.createSignatureCard(null, null);
- resultCode = CARD_FOUND;
- } catch (CardNotSupportedException e) {
- resultCode = CARD_NOT_SUPPORTED;
- signatureCard = null;
- }
- return;
- }
- signatureCard = null;
- resultCode = NO_CARD;
- // find pcsc support
- if (smartCardIO.isPCSCSupported()) {
- // find supported card
- if (smartCardIO.isTerminalPresent()) {
- Map<CardTerminal, Card> newCards = null;
- if (sleep > 0) {
- smartCardIO.waitForInserted(sleep);
-
- }
- newCards = smartCardIO.getCards();
- for (CardTerminal cardTerminal : newCards.keySet()) {
- try {
- Card c = newCards.get(cardTerminal);
- if (c == null) {
- throw new CardNotSupportedException();
- }
- signatureCard = factory.createSignatureCard(c, cardTerminal);
- ATR atr = newCards.get(cardTerminal).getATR();
- log.trace("Found supported card (" + signatureCard.toString() + ") "
- + "in terminal '" + cardTerminal.getName() + "', ATR = "
- + toString(atr.getBytes()) + ".");
- resultCode = CARD_FOUND;
- break;
-
- } catch (CardNotSupportedException e) {
- Card c = newCards.get(cardTerminal);
- if (c != null) {
- ATR atr = c.getATR();
- log.info("Found unsupported card" + " in terminal '"
- + cardTerminal.getName() + "', ATR = "
- + toString(atr.getBytes()) + ".");
- } else {
- log.info("Found unsupported card in terminal '"
- + cardTerminal.getName() + "' without ATR");
- }
- resultCode = CARD_NOT_SUPPORTED;
- }
- }
- } else {
- resultCode = TERMINAL_NOT_PRESENT;
- }
- } else {
- resultCode = PC_SC_NOT_SUPPORTED;
- }
- }
-
- public synchronized SignatureCard getSignatureCard(Locale locale) {
- if (signatureCard != null) {
- signatureCard.setLocale(locale);
- }
- return signatureCard;
- }
-
- public int getResultCode() {
- return resultCode;
- }
-
- public static String toString(byte[] b) {
- StringBuffer sb = new StringBuffer();
- sb.append('[');
- if (b != null && b.length > 0) {
- sb.append(Integer.toHexString((b[0] & 240) >> 4));
- sb.append(Integer.toHexString(b[0] & 15));
- for (int i = 1; i < b.length; i++) {
- sb.append((i % 32 == 0) ? '\n' : ':');
- sb.append(Integer.toHexString((b[i] & 240) >> 4));
- sb.append(Integer.toHexString(b[i] & 15));
- }
- }
- sb.append(']');
- return sb.toString();
- }
-
- public static boolean isUseSWCard() {
- return useSWCard;
- }
-
- public static void setUseSWCard(boolean useSWCard) {
- SMCCHelper.useSWCard = useSWCard;
- }
-}
diff --git a/mocca-1.2.11/smcc/src/main/java/at/gv/egiz/smcc/util/SmartCardIO.java b/mocca-1.2.11/smcc/src/main/java/at/gv/egiz/smcc/util/SmartCardIO.java deleted file mode 100644 index b1866894..00000000 --- a/mocca-1.2.11/smcc/src/main/java/at/gv/egiz/smcc/util/SmartCardIO.java +++ /dev/null @@ -1,204 +0,0 @@ -/* -* Copyright 2008 Federal Chancellery Austria and -* Graz University of Technology -* -* 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. -*/ -package at.gv.egiz.smcc.util;
-
-import java.security.NoSuchAlgorithmException; -import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.smartcardio.Card;
-import javax.smartcardio.CardException;
-import javax.smartcardio.CardTerminal;
-import javax.smartcardio.CardTerminals;
-import javax.smartcardio.TerminalFactory;
-import javax.smartcardio.CardTerminals.State;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- *
- * @author mcentner
- */
-public class SmartCardIO {
-
- private static final int STATE_INITIALIZED = 1;
-
- private static final int STATE_TERMINAL_FACTORY = 2;
-
- private static final int STATE_TERMINALS = 3;
-
- private static Log log = LogFactory.getLog(SmartCardIO.class);
-
- final Map<CardTerminal, Card> terminalCard_ = new HashMap<CardTerminal, Card>();
-
- int state_ = STATE_INITIALIZED;
-
- TerminalFactory terminalFactory_ = null;
-
- CardTerminals cardTerminals_;
-
- private void updateTerminalFactory() {
- TerminalFactory terminalFactory; - try { - terminalFactory = TerminalFactory.getInstance("PC/SC", null); - } catch (NoSuchAlgorithmException e) { - log.info("Failed to get TerminalFactory of type 'PC/SC'.", e); - terminalFactory = TerminalFactory.getDefault(); - }
- log.debug("TerminalFactory : " + terminalFactory);
- if ("PC/SC".equals(terminalFactory.getType())) {
- terminalFactory_ = terminalFactory;
- }
- if(state_ < STATE_TERMINAL_FACTORY) {
- state_ = STATE_TERMINAL_FACTORY;
- }
- }
-
- public boolean isPCSCSupported() {
- if(state_ < STATE_TERMINAL_FACTORY) {
- updateTerminalFactory();
- }
- return terminalFactory_ != null;
- }
-
- private void updateCardTerminals() {
- if(terminalFactory_ != null) {
- cardTerminals_ = terminalFactory_.terminals();
- }
- log.debug("CardTerminals : " + cardTerminals_);
- if (state_ < STATE_TERMINALS) {
- state_ = STATE_TERMINALS;
- }
- }
-
- public CardTerminals getCardTerminals() {
- if(state_ < STATE_TERMINAL_FACTORY) {
- updateTerminalFactory();
- }
- if(state_ < STATE_TERMINALS) {
- updateCardTerminals();
- }
- return cardTerminals_;
- }
-
- public boolean isTerminalPresent() {
- CardTerminals cardTerminals = getCardTerminals();
- if (cardTerminals != null) {
- List<CardTerminal> terminals = null;
- try {
- terminals = cardTerminals.list(State.ALL);
-
- // logging
- if(log.isInfoEnabled()) {
- if (terminals == null || terminals.isEmpty()) {
- log.info("No card terminal found.");
- } else {
- StringBuffer msg = new StringBuffer();
- msg.append("Found " + terminals.size() + " card terminal(s):");
- for (CardTerminal terminal : terminals) {
- msg.append("\n " + terminal.getName());
- }
- log.info(msg.toString());
- }
- }
-
- return terminals != null && !terminals.isEmpty();
- } catch (CardException e) {
- log.info("Failed to list card terminals.", e);
- return false;
- }
- } else {
- return false;
- }
- }
-
- private Map<CardTerminal, Card> updateCards() {
-
- // clear card references if removed
- try {
- log.trace("terminals.list(State.CARD_REMOVAL)");
- for (CardTerminal terminal : cardTerminals_.list(CardTerminals.State.CARD_REMOVAL)) {
- Card card = terminalCard_.remove(terminal);
- log.trace("card removed : " + card);
- }
- } catch (CardException e) {
- log.debug(e);
- }
-
- // check inserted cards
- Map<CardTerminal, Card> newCards = new HashMap<CardTerminal, Card>();
- try {
- log.trace("terminals.list(State.CARD_INSERTION)");
- for (CardTerminal terminal : cardTerminals_.list(CardTerminals.State.CARD_INSERTION)) {
-
- Card card = null;
- try { - log.trace("Trying to connect to card."); - // try to connect to card
- card = terminal.connect("*");
- } catch (CardException e) {
- log.trace("Failed to connect to card.", e);
- }
-
- // have we seen this card before?
- if (terminalCard_.put(terminal, card) == null) {
- terminalCard_.put(terminal, card);
- newCards.put(terminal, card);
- log.trace("terminal '" + terminal + "' card inserted : " + card);
- }
- }
- } catch (CardException e) {
- log.debug(e);
- }
- return newCards;
-
- }
-
- public Map<CardTerminal, Card> getCards() {
- if(state_ < STATE_TERMINAL_FACTORY) {
- updateTerminalFactory();
- }
- if(state_ < STATE_TERMINALS) {
- updateCardTerminals();
- }
- updateCards();
- Map<CardTerminal, Card> terminalCard = new HashMap<CardTerminal, Card>();
- terminalCard.putAll(terminalCard_);
- return Collections.unmodifiableMap(terminalCard);
- }
-
- public Map<CardTerminal, Card> waitForInserted(int timeout) {
- if(state_ < STATE_TERMINAL_FACTORY) {
- updateTerminalFactory();
- }
- if(state_ < STATE_TERMINALS) {
- updateCardTerminals();
- }
- try {
- // just waiting for a short period of time to allow for abort
- cardTerminals_.waitForChange(timeout);
- } catch (CardException e) {
- log.debug("CardTerminals.waitForChange(" + timeout + ") failed.", e);
- }
- Map<CardTerminal, Card> newCards = new HashMap<CardTerminal, Card>();
- newCards.putAll(updateCards());
- return Collections.unmodifiableMap(newCards);
- }
-}
\ No newline at end of file diff --git a/mocca-1.2.11/smcc/src/main/java/at/gv/egiz/smcc/util/TransparentFileInputStream.java b/mocca-1.2.11/smcc/src/main/java/at/gv/egiz/smcc/util/TransparentFileInputStream.java deleted file mode 100644 index 781f9137..00000000 --- a/mocca-1.2.11/smcc/src/main/java/at/gv/egiz/smcc/util/TransparentFileInputStream.java +++ /dev/null @@ -1,194 +0,0 @@ -/* -* Copyright 2008 Federal Chancellery Austria and -* Graz University of Technology -* -* 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. -*/ -package at.gv.egiz.smcc.util; - -import java.io.IOException; -import java.io.InputStream; - -public abstract class TransparentFileInputStream extends InputStream { - - private final int chunkSize = 256; - - private byte[] buf = new byte[chunkSize]; - private int start = 0; - private int end = 0; - - private int offset = 0; - - private int length = -1; - - private int limit = -1; - - private int mark = -1; - - private int readlimit = -1; - - public TransparentFileInputStream() { - } - - public TransparentFileInputStream(int length) { - this.length = length; - } - - public void setLimit(int limit) { - this.limit = limit; - } - - private int fill() throws IOException { - if (start == end && (limit < 0 || offset < limit)) { - int l; - if (limit > 0 && limit - offset < chunkSize) { - l = limit - offset; - } else if (length > 0) { - if (length - offset < chunkSize) { - l = length - offset; - } else { - l = chunkSize - 1; - } - } else { - l = chunkSize; - } - byte[] b = readBinary(offset, l); - offset += b.length; - if (mark < 0) { - start = 0; - end = b.length; - System.arraycopy(b, 0, buf, start, b.length); - } else { - if (end - mark + b.length > buf.length) { - // double buffer size - byte[] nbuf = new byte[buf.length * 2]; - System.arraycopy(buf, mark, nbuf, 0, end - mark); - buf = nbuf; - } else { - System.arraycopy(buf, mark, buf, 0, end - mark); - } - start = start - mark; - end = end - mark + b.length; - mark = 0; - System.arraycopy(b, 0, buf, start, b.length); - } - if (l > b.length) { - // end of file reached - setLimit(offset); - } - } - return end - start; - } - - protected abstract byte[] readBinary(int offset, int len) throws IOException; - - @Override - public int read() throws IOException { - int b = (fill() > 0) ? 0xFF & buf[start++] : -1; - if (readlimit > 0 && start > readlimit) { - mark = -1; - readlimit = -1; - } - return b; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (b == null) { - throw new NullPointerException(); - } else if (off < 0 || len < 0 || len > b.length - off) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return 0; - } - - int count = 0; - int l; - while (count < len) { - if (fill() > 0) { - l = Math.min(end - start, len - count); - System.arraycopy(buf, start, b, off, l); - start += l; - off += l; - count += l; - if (readlimit > 0 && start > readlimit) { - mark = -1; - readlimit = -1; - } - } else { - return (count > 0) ? count : -1; - } - } - - return count; - - } - - @Override - public synchronized void mark(int readlimit) { - this.readlimit = readlimit; - mark = start; - } - - @Override - public boolean markSupported() { - return true; - } - - @Override - public synchronized void reset() throws IOException { - if (mark < 0) { - throw new IOException(); - } else { - start = mark; - } - } - - @Override - public long skip(long n) throws IOException { - - if (n <= 0) { - return 0; - } - - if (n <= end - start) { - start += n; - return n; - } else { - - mark = -1; - - long remaining = n - (end - start); - start = end; - - if (limit >= 0 && limit < offset + remaining) { - remaining -= limit - offset; - offset = limit; - return n - remaining; - } - - if (length >= 0 && length < offset + remaining) { - remaining -= length - offset; - offset = length; - return n - remaining; - } - - offset += remaining; - - return n; - - } - - } - -} |