Path: blob/master/src/java.smartcardio/share/classes/javax/smartcardio/ATR.java
41153 views
/*1* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.smartcardio;2627import java.util.*;2829/**30* A Smart Card's answer-to-reset bytes. A Card's ATR object can be obtained31* by calling {@linkplain Card#getATR}.32* This class does not attempt to verify that the ATR encodes a semantically33* valid structure.34*35* <p>Instances of this class are immutable. Where data is passed in or out36* via byte arrays, defensive cloning is performed.37*38* @see Card#getATR39*40* @since 1.641* @author Andreas Sterbenz42* @author JSR 268 Expert Group43*/44public final class ATR implements java.io.Serializable {4546private static final long serialVersionUID = 6695383790847736493L;4748private byte[] atr;4950private transient int startHistorical, nHistorical;5152/**53* Constructs an ATR from a byte array.54*55* @param atr the byte array containing the answer-to-reset bytes56* @throws NullPointerException if <code>atr</code> is null57*/58public ATR(byte[] atr) {59this.atr = atr.clone();60parse();61}6263private void parse() {64if (atr.length < 2) {65return;66}67if ((atr[0] != 0x3b) && (atr[0] != 0x3f)) {68return;69}70int t0 = (atr[1] & 0xf0) >> 4;71int n = atr[1] & 0xf;72int i = 2;73while ((t0 != 0) && (i < atr.length)) {74if ((t0 & 1) != 0) {75i++;76}77if ((t0 & 2) != 0) {78i++;79}80if ((t0 & 4) != 0) {81i++;82}83if ((t0 & 8) != 0) {84if (i >= atr.length) {85return;86}87t0 = (atr[i++] & 0xf0) >> 4;88} else {89t0 = 0;90}91}92int k = i + n;93if ((k == atr.length) || (k == atr.length - 1)) {94startHistorical = i;95nHistorical = n;96}97}9899/**100* Returns a copy of the bytes in this ATR.101*102* @return a copy of the bytes in this ATR.103*/104public byte[] getBytes() {105return atr.clone();106}107108/**109* Returns a copy of the historical bytes in this ATR.110* If this ATR does not contain historical bytes, an array of length111* zero is returned.112*113* @return a copy of the historical bytes in this ATR.114*/115public byte[] getHistoricalBytes() {116byte[] b = new byte[nHistorical];117System.arraycopy(atr, startHistorical, b, 0, nHistorical);118return b;119}120121/**122* Returns a string representation of this ATR.123*124* @return a String representation of this ATR.125*/126public String toString() {127return "ATR: " + atr.length + " bytes";128}129130/**131* Compares the specified object with this ATR for equality.132* Returns true if the given object is also an ATR and its bytes are133* identical to the bytes in this ATR.134*135* @param obj the object to be compared for equality with this ATR136* @return true if the specified object is equal to this ATR137*/138public boolean equals(Object obj) {139if (this == obj) {140return true;141}142if (obj instanceof ATR == false) {143return false;144}145ATR other = (ATR)obj;146return Arrays.equals(this.atr, other.atr);147}148149/**150* Returns the hash code value for this ATR.151*152* @return the hash code value for this ATR.153*/154public int hashCode() {155return Arrays.hashCode(atr);156}157158private void readObject(java.io.ObjectInputStream in)159throws java.io.IOException, ClassNotFoundException {160atr = (byte[])in.readUnshared();161parse();162}163164}165166167