www.pudn.com > cryptix-asn1-0.1.11.zip > SetOf.java


/* $Id: SetOf.java,v 1.8 2001/06/30 01:56:29 raif Exp $ 
 * 
 * Copyright (C) 1997-2001 The Cryptix Foundation Limited. All rights reserved. 
 * 
 * Use, modification, copying and distribution of this software is subject to 
 * the terms and conditions of the Cryptix General Licence. You should have 
 * received a copy of the Cryptix General Licence along with this library; if 
 * not, you can download a copy from http://www.cryptix.org/ 
 */ 
package cryptix.asn1.lang; 
 
import cryptix.asn1.io.ASNReader; 
import cryptix.asn1.io.ASNWriter; 
import cryptix.asn1.io.ElementNotFoundException; 
 
import org.apache.log4j.Category; 
 
import java.io.EOFException; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.ListIterator; 
 
/** 
 * The abstract implementation of the ASN.1 SET OF type.

* * The value of such type is a java.util.ArrayList. This data * structure is supposed to hold the concrete value sets of 0 or more instances * of the SET OF components. For example, if this is an instance of SET OF * TypeA, then the components of this SET OF contains TypeA, * and its value is a java.util.ArrayList of 0 or more values of * TypeA. The components field of this type is itself a * java.util.ArrayList.

* * A convenience method to return the value as a java.util.ArrayList * is supplied.

* * @version $Revision: 1.8 $ * @author Raif S. Naffah */ public abstract class SetOf extends CompoundType { // Constants and vars // ....................................................................... static Category cat = Category.getInstance(SetOf.class.getName()); // Constructor(s) // ....................................................................... public SetOf(Tag tag) { super("", tag); } public SetOf(String name, Tag tag) { super(name, tag); } /** * Constructs a new instance of a SET_OF type, given a designated Tag and a * designated initial value. * * @param name the name of this instance. * @param tag the designated Tag value. * @param value the designated initial value. * @exception ClassCastException if the designated value is not an ArrayList. */ public SetOf(String name, Tag tag, Object value) { super(name, tag); if (value != null) if (value instanceof ArrayList) value(value); else throw new ClassCastException(); } // Redefinition of methods in superclass Type // ....................................................................... /** * Decodes a SET OF from an input stream. * * @param is the ASN.1 stream to read from. * @exception IOException if an exception occurs during the operation. */ public void decode(ASNReader is) throws IOException { String cn = this.getClass().getName(); cat.debug("==> "+cn+".decode()"); this.reset(); is.mark(Integer.MAX_VALUE); ASNReader local = is.decodeStructure(this); if (local == null) { cat.warn(cn+" not found. Backtracking..."); is.reset(); throw new ElementNotFoundException(cn); } Iterator it; IType t; int found; ArrayList e; outer: while (true) { e = cloneComponents(); cat.info("Looking for a valid "+cn+" (SET OF) frame..."); inner: while (true) { for (it = e.iterator(), found = 0; it.hasNext(); ) { t = (Type) it.next(); if (t.isBlank()) { try { local.mark(Integer.MAX_VALUE); cat.info("Looking for "+t.getClass().getName()); t.decode(local); cat.info("Found "+t.getClass().getName()); found++; } catch (EOFException x) { cat.info("Exhausted the input stream. Breaking..."); for (it = e.iterator(); it.hasNext(); ) { t = (Type) it.next(); if (t.isBlank() && !t.isOptional()) throw new ASNException("After completely parsing the last "+cn +" (SET OF) frame, a non optional type ("+t.getClass().getName() +") was found missing"); } // for (it = e.iterator(); it.hasNext(); ) // if (!((Type) it.next()).isBlank()) { if (found > 0) { cat.info("Eureka! Adding last frame to "+cn+"'s (SET OF) collection..."); this.iterator().add(e); break outer; } break outer; } catch (ElementNotFoundException x) { cat.warn(String.valueOf(x)+". Backtracking..."); if (!t.isOptional()) local.reset(); } } } if (found == 0) { cat.info("Found no match. Breaking..."); for (it = e.iterator(); it.hasNext(); ) { t = (Type) it.next(); if (t.isBlank() && !t.isOptional()) throw new ASNException("After completely parsing the last "+cn +" (SET OF) frame, a non optional type ("+t.getClass().getName() +") was found missing"); } for (it = e.iterator(); it.hasNext(); ) if (!((Type) it.next()).isBlank()) { cat.info("Eureka! Adding last frame to "+cn+"'s (SET OF) collection..."); this.iterator().add(e); break outer; } break outer; } } } cat.debug("<== "+cn+".decode()"); } /** * Sets the current value of this instance to the designated one. For a * compound type, the value is expected to always be an ArrayList or an * ANY with an ArrayList object as its value. * * @param value the new value to assign to this instance. */ public void value(Object value) { String cn = this.getClass().getName(); cat.debug("==> "+cn+".value()"); cat.debug("value="+String.valueOf(value)); cat.debug("value is a "+String.valueOf(value.getClass().getName())); if (value instanceof IType) cat.debug("Tag="+String.valueOf( ((IType) value).tag() )); this.reset(); ArrayList e; Iterator frame; IType td; if (value instanceof IType) { value = ((IType) value).value(); cat.debug("value now="+String.valueOf(value)); cat.debug("value is now a "+String.valueOf(value.getClass().getName())); if (value instanceof IType) cat.debug("Tag="+String.valueOf( ((IType) value).tag() )); } if (value instanceof ArrayList) { cat.warn("Assume a SEQUENCE OF one component..."); frame = ((ArrayList) value).iterator(); for (int i = 1; frame.hasNext(); i++) { cat.info("Processing frame #"+String.valueOf(i)+" of "+cn); td = (IType) cloneComponents().iterator().next(); cat.info("Assigning value to "+td.getClass().getName()); td.value(frame.next()); this.iterator().add(td); } } else { RuntimeException x = new RuntimeException(); x.printStackTrace(System.err); throw x; } cat.debug("<== "+cn+".value()"); } // java.lang.Object overloaded methods // ....................................................................... /** * Returns a string representation of this instance. * * @return a string representation of this instance. */ public String toString() { String cn = this.getClass().getName(); String ls = System.getProperty("line.separator"); StringBuffer sb = new StringBuffer(ls); sb.append("-- Begin ").append(cn).append(" (SET OF)").append(ls); int i = 1; for (Iterator it = this.iterator(); it.hasNext(); ) { Object t = it.next(); sb.append("-- frame #").append(i++) .append(" (").append(t.getClass().getName()).append("): ") .append(String.valueOf(t)).append(ls); } sb.append("-- End ").append(cn).append(" (SET OF)"); return sb.toString(); } }