* 'INTEGER' and 'ENUMERATED' types which contain a BigInteger value renamed to 'BigINTEGER' and 'BigENUMERATED'.
* Some bugs were fixed.
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import jp.bitmeister.asn1.type.builtin.BigENUMERATED;
+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
import jp.bitmeister.asn1.type.builtin.ENUMERATED;
import jp.bitmeister.asn1.type.builtin.INTEGER;
*
* <p>
* If a field annotated as {@code @ASN1Enumeration} is present in a definition
- * of a sub-class of {@code INTEGER} or {@code ENUMERATED}, value that can be
- * contained in the type is limited to values of {@code @ASN1Enumeration}
- * fields. An {@code @ASN1Enumeration} field must be a {@code public}
- * {@code static} {@code final} field and the type shall be {@code int},
- * {@code long} or {@code BigInteger}. Each value of {@code @ASN1Enumeration}
- * fields appearing in definition of a type must be distinct from the others. A
- * sub-class of {@code ENUMERATED} must have at least one
- * {@code @ASN1Enumeration} field.
+ * of a sub-class of {@code INTEGER}, {@code ENUMERATED}, {@code BigINTEGER} or
+ * {@code BigENUMERATED}, value that can be contained in the type is limited to
+ * values of {@code @ASN1Enumeration} fields. An {@code @ASN1Enumeration} field
+ * must be a {@code public} {@code static} {@code final} field and the type
+ * shall be {@code int}, {@code long} or {@code BigInteger} (only for
+ * {@code BigINTEGER} or {@code BigENUMERATED}). Each value of
+ * {@code @ASN1Enumeration} fields appearing in definition of a type must be
+ * distinct from the others. A sub-class of {@code ENUMERATED} or
+ * {@code BigENUMERATED} must have at least one {@code @ASN1Enumeration} field.
* </p>
* <p>
* For example, following ASN.1 definition :
*
* @see INTEGER
* @see ENUMERATED
+ * @see BigINTEGER
+ * @see BigENUMERATED
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
import jp.bitmeister.asn1.type.builtin.ANY;
import jp.bitmeister.asn1.type.builtin.BIT_STRING;
import jp.bitmeister.asn1.type.builtin.BOOLEAN;
+import jp.bitmeister.asn1.type.builtin.BigENUMERATED;
+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
import jp.bitmeister.asn1.type.builtin.CHOICE;
import jp.bitmeister.asn1.type.builtin.ENUMERATED;
import jp.bitmeister.asn1.type.builtin.INTEGER;
*
* @see
* jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .IntegerType)
+ * .builtin.INTEGER)
*/
public Void visit(INTEGER data) throws ASN1DecodingException {
+ data.set(new BigInteger(readStream(readLength())).longValue());
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .IntegerType)
+ */
+ public Void visit(BigINTEGER data) throws ASN1DecodingException {
data.set(new BigInteger(readStream(readLength())));
return null;
}
*
* @see
* jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .EnumeratedType)
+ * .builtin.ENUMERATED)
*/
public Void visit(ENUMERATED data) throws ASN1DecodingException {
visit((INTEGER) data);
return null;
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .EnumeratedType)
+ */
+ public Void visit(BigENUMERATED data) throws ASN1DecodingException {
+ visit((BigINTEGER) data);
+ return null;
+ }
/*
* (non-Javadoc)
import jp.bitmeister.asn1.type.builtin.BIT_STRING;
import jp.bitmeister.asn1.type.builtin.BOOLEAN;
import jp.bitmeister.asn1.type.builtin.CHOICE;
+import jp.bitmeister.asn1.type.builtin.BigENUMERATED;
+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
import jp.bitmeister.asn1.type.builtin.ENUMERATED;
import jp.bitmeister.asn1.type.builtin.INTEGER;
import jp.bitmeister.asn1.type.builtin.NULL;
return newPrimitiveOctets(data.value() ? (byte) 0xff : (byte) 0x00);
}
+ /* (non-Javadoc)
+ * @see jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type.builtin.INTEGER)
+ */
+ public EncodedOctets visit(INTEGER data) throws ASN1EncodingException {
+ return newPrimitiveOctets(BigInteger.valueOf(data.value()).toByteArray());
+ }
+
/*
* (non-Javadoc)
*
* jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
* .builtin.INTEGER)
*/
- public EncodedOctets visit(INTEGER data) {
+ public EncodedOctets visit(BigINTEGER data) {
return newPrimitiveOctets(data.value().toByteArray());
}
+
+ /* (non-Javadoc)
+ * @see jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type.builtin.ENUMERATED)
+ */
+ public EncodedOctets visit(ENUMERATED data) throws ASN1EncodingException {
+ return visit((INTEGER)data);
+ }
/*
* (non-Javadoc)
* jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
* .builtin.ENUMERATED)
*/
- public EncodedOctets visit(ENUMERATED data) {
- return visit((INTEGER) data);
+ public EncodedOctets visit(BigENUMERATED data) {
+ return visit((BigINTEGER) data);
}
-
+
/*
* (non-Javadoc)
*
import jp.bitmeister.asn1.type.builtin.ANY;
import jp.bitmeister.asn1.type.builtin.BIT_STRING;
import jp.bitmeister.asn1.type.builtin.BOOLEAN;
+import jp.bitmeister.asn1.type.builtin.BigENUMERATED;
+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
import jp.bitmeister.asn1.type.builtin.CHOICE;
import jp.bitmeister.asn1.type.builtin.ENUMERATED;
import jp.bitmeister.asn1.type.builtin.INTEGER;
*/
@Override
public void characters(String characters) {
+ data.set(Long.valueOf(characters));
+ }
+
+ };
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.BigINTEGER)
+ */
+ public DataDecoder visit(final BigINTEGER data) {
+ return new DataDecoder() {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#startChildElement
+ * (java.lang.String)
+ */
+ @Override
+ void startChildElement(String qName) {
+ data.set(qName);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#characters
+ * (java.lang.String)
+ */
+ @Override
+ public void characters(String characters) {
data.set(new BigInteger(characters));
}
};
}
-
+
/*
* (non-Javadoc)
*
public DataDecoder visit(ENUMERATED data) {
return visit((INTEGER) data);
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.BigENUMERATED)
+ */
+ public DataDecoder visit(BigENUMERATED data) {
+ return visit((BigINTEGER) data);
+ }
/*
* (non-Javadoc)
void startElement(String qName) {
if (BOOLEAN.class.isAssignableFrom(data.componentType())
|| ENUMERATED.class.isAssignableFrom(data.componentType())
+ || BigENUMERATED.class.isAssignableFrom(data.componentType())
|| CHOICE.class.isAssignableFrom(data.componentType())) {
useXmlValueList = true;
}
import jp.bitmeister.asn1.processor.ASN1Visitor;
import jp.bitmeister.asn1.type.ASN1Module;
import jp.bitmeister.asn1.type.ASN1Type;
+import jp.bitmeister.asn1.type.AbstractInteger;
import jp.bitmeister.asn1.type.CollectionType;
import jp.bitmeister.asn1.type.ConstructiveType;
import jp.bitmeister.asn1.type.ElementSpecification;
import jp.bitmeister.asn1.type.builtin.ANY;
import jp.bitmeister.asn1.type.builtin.BIT_STRING;
import jp.bitmeister.asn1.type.builtin.BOOLEAN;
+import jp.bitmeister.asn1.type.builtin.BigENUMERATED;
+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
import jp.bitmeister.asn1.type.builtin.CHOICE;
import jp.bitmeister.asn1.type.builtin.ENUMERATED;
import jp.bitmeister.asn1.type.builtin.INTEGER;
* jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
* .builtin.INTEGER)
*/
- public String visit(INTEGER data) {
- String numberId = data.identifier();
- if (numberId != null) {
- return TAG_START + numberId + SINGLE_TAG_END;
- } else {
- return data.value().toString();
- }
+ public String visit(INTEGER data) throws ASN1EncodingException {
+ return encodeInteger(data);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.BigINTEGER)
+ */
+ public String visit(BigINTEGER data) {
+ return encodeInteger(data);
}
/*
* .builtin.ENUMERATED)
*/
public String visit(ENUMERATED data) {
- return visit((INTEGER) data);
+ return encodeInteger(data);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.BigENUMERATED)
+ */
+ public String visit(BigENUMERATED data) {
+ return encodeInteger(data);
}
/*
}
/**
+ * Encodes an ASN.1 'INTEGER' or 'ENUMERATED' data.
+ *
+ * @param data
+ * The integer data.
+ * @return The XER representation of the data.
+ */
+ private String encodeInteger(AbstractInteger<?> data) {
+ String numberId = data.identifier();
+ if (numberId != null) {
+ return TAG_START + numberId + SINGLE_TAG_END;
+ } else {
+ return data.value().toString();
+ }
+ }
+
+ /**
* Encodes each element of the {@code ConstructiveType} data.
*
* @param data
builder = new StringBuilder();
if (BOOLEAN.class.isAssignableFrom(data.componentType())
|| ENUMERATED.class.isAssignableFrom(data.componentType())
+ || BigENUMERATED.class.isAssignableFrom(data.componentType())
|| CHOICE.class.isAssignableFrom(data.componentType())) {
for (ASN1Type e : data.collection()) {
builder.append(e.accept(this));
*/
@SuppressWarnings("serial")
public class ASN1DecodingException extends ASN1Exception {
+
+ /**
+ * Instantiate an {@code ASN1DecodingException}.
+ */
+ public ASN1DecodingException() {
+ }
+
+ /**
+ * Instantiate an {@code ASN1DecodingException} with specified error message.
+ *
+ * @param message
+ * The error message.
+ */
+ public ASN1DecodingException(String message) {
+ super(message);
+ }
+
}
*/
@SuppressWarnings("serial")
public class ASN1EncodingException extends ASN1Exception {
+
+ /**
+ * Instantiate an {@code ASN1EncodingException}.
+ */
+ public ASN1EncodingException() {
+ }
+
+ /**
+ * Instantiate an {@code ASN1EncodingException} with specified error message.
+ *
+ * @param message
+ * The error message.
+ */
+ public ASN1EncodingException(String message) {
+ super(message);
+ }
+
}
public class ASN1Exception extends Exception {
protected DetailedMessage message;
+
+ /**
+ * Instantiate an {@code ASN1Exception}.
+ */
+ public ASN1Exception() {
+ }
+
+ /**
+ * Instantiate an {@code ASN1Exception} with specified error message.
+ *
+ * @param message
+ * The error message.
+ */
+ public ASN1Exception(String message) {
+ super(message);
+ }
/**
* Set detailed message of this exception.
*/
@SuppressWarnings("serial")
public class ASN1IllegalArgument extends ASN1RuntimeException {
+
+ /**
+ * Instantiate an {@code ASN1IllegalArgument}.
+ */
+ public ASN1IllegalArgument() {
+ }
+
+ /**
+ * Instantiate an {@code ASN1IllegalArgument} with specified error message.
+ *
+ * @param message
+ * The error message.
+ */
+ public ASN1IllegalArgument(String message) {
+ super(message);
+ }
+
}
*/
@SuppressWarnings("serial")
public class ASN1IllegalDefinition extends ASN1RuntimeException {
+
+ /**
+ * Instantiate an {@code ASN1IllegalDefinition}.
+ */
+ public ASN1IllegalDefinition() {
+ }
+
+ /**
+ * Instantiate an {@code ASN1IllegalDefinition} with specified error message.
+ *
+ * @param message
+ * The error message.
+ */
+ public ASN1IllegalDefinition(String message) {
+ super(message);
+ }
+
}
*/
@SuppressWarnings("serial")
public class ASN1InvalidDataValue extends ASN1RuntimeException {
+
+ /**
+ * Instantiate an {@code ASN1InvalidDataValue}.
+ */
+ public ASN1InvalidDataValue() {
+ }
+
+ /**
+ * Instantiate an {@code ASN1InvalidDataValue} with specified error message.
+ *
+ * @param message
+ * The error message.
+ */
+ public ASN1InvalidDataValue(String message) {
+ super(message);
+ }
+
}
public class ASN1RuntimeException extends RuntimeException {
private DetailedMessage message;
-
+
+ /**
+ * Instantiate an {@code ASN1RuntimeException}.
+ */
+ public ASN1RuntimeException() {
+ }
+
+ /**
+ * Instantiate an {@code ASN1RuntimeException} with specified error message.
+ *
+ * @param message
+ * The error message.
+ */
+ public ASN1RuntimeException(String message) {
+ super(message);
+ }
+
/**
* Set detailed message of this exception.
*
import jp.bitmeister.asn1.type.ASN1TagMode;
import jp.bitmeister.asn1.type.ASN1TagValue;
import jp.bitmeister.asn1.type.ASN1Type;
+import jp.bitmeister.asn1.type.AbstractInteger;
import jp.bitmeister.asn1.type.CollectionType;
import jp.bitmeister.asn1.type.ConstructiveType;
import jp.bitmeister.asn1.type.ElementSpecification;
import jp.bitmeister.asn1.type.builtin.ANY;
import jp.bitmeister.asn1.type.builtin.BIT_STRING;
import jp.bitmeister.asn1.type.builtin.BOOLEAN;
+import jp.bitmeister.asn1.type.builtin.BigENUMERATED;
+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
import jp.bitmeister.asn1.type.builtin.CHOICE;
import jp.bitmeister.asn1.type.builtin.ENUMERATED;
import jp.bitmeister.asn1.type.builtin.INTEGER;
builder.append(data.value() ? "TRUE" : "FALSE");
return null;
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1
+ * .type.builtin.INTEGER)
+ */
+ public Void visit(INTEGER data) throws ASN1RuntimeException {
+ writeInteger((AbstractInteger<?>) data);
+ return null;
+ }
/*
* (non-Javadoc)
*
* @see
* jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.INTEGER)
+ * .builtin.BigINTEGER)
*/
- public Void visit(INTEGER data) {
- String numberId = data.identifier();
- if (numberId != null) {
- builder.append(numberId);
- }
- builder.append(NUMBER_OPEN).append(data.value()).append(NUMBER_CLOSE);
+ public Void visit(BigINTEGER data) {
+ writeInteger((AbstractInteger<?>)data);
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1
+ * .type.builtin.ENUMERATED)
+ */
+ public Void visit(ENUMERATED data) {
+ writeInteger((AbstractInteger<?>) data);
return null;
}
*
* @see
* jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
- * .builtin.ENUMERATED)
+ * .builtin.BigENUMERATED)
*/
- public Void visit(ENUMERATED data) {
- visit((INTEGER) data);
+ public Void visit(BigENUMERATED data) {
+ writeInteger((AbstractInteger<?>)data);
return null;
}
}
/**
+ * Writes value and identifier of an ASN.1 'INTEGER' or 'ENUMERATED' value.
+ * @param data The integer data.
+ */
+ private void writeInteger(AbstractInteger<?> data) {
+ String numberId = data.identifier();
+ if (numberId != null) {
+ builder.append(numberId);
+ }
+ builder.append(NUMBER_OPEN).append(data.value()).append(NUMBER_CLOSE);
+ }
+
+ /**
* Writes descriptions of each element of {@code ConstructiveType}.
*
* @param data
import jp.bitmeister.asn1.type.builtin.ANY;
import jp.bitmeister.asn1.type.builtin.BIT_STRING;
import jp.bitmeister.asn1.type.builtin.BOOLEAN;
+import jp.bitmeister.asn1.type.builtin.BigENUMERATED;
+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
import jp.bitmeister.asn1.type.builtin.CHOICE;
import jp.bitmeister.asn1.type.builtin.ENUMERATED;
import jp.bitmeister.asn1.type.builtin.INTEGER;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(BOOLEAN data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(INTEGER data) throws E;
+
+ /**
+ * Visits the {@code BigINTEGER} data.
+ *
+ * @param data
+ * The data to be visited.
+ * @return Result.
+ * @throws E
+ * When an error occurred in the {@code accept} method.
+ */
+ public R visit(BigINTEGER data) throws E;
/**
* Visits the {@code BIT_STRING} data.
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(BIT_STRING data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(OCTET_STRING data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(NULL data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(OBJECT_IDENTIFIER data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(REAL data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(ENUMERATED data) throws E;
/**
+ * Visits the {@code BigENUMERATED} data.
+ *
+ * @param data
+ * The data to be visited.
+ * @return Result.
+ * @throws E
+ * When an error occurred in the {@code accept} method.
+ */
+ public R visit(BigENUMERATED data) throws E;
+
+ /**
* Visits the {@code RELATIVE_OID} data.
*
* @param data
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(RELATIVE_OID data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(ANY data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(CHOICE data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(SEQUENCE_OF<? extends ASN1Type> data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(SEQUENCE data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(SET_OF<? extends ASN1Type> data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(SET data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(StringType data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(TimeType data) throws E;
* The data to be visited.
* @return Result.
* @throws E
- * When an error occured in the {@code accept} method.
+ * When an error occurred in the {@code accept} method.
*/
public R visit(UnknownType data) throws E;
import jp.bitmeister.asn1.type.builtin.ANY;
import jp.bitmeister.asn1.type.builtin.BIT_STRING;
import jp.bitmeister.asn1.type.builtin.BOOLEAN;
+import jp.bitmeister.asn1.type.builtin.BigENUMERATED;
+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
import jp.bitmeister.asn1.type.builtin.CHOICE;
import jp.bitmeister.asn1.type.builtin.ENUMERATED;
import jp.bitmeister.asn1.type.builtin.INTEGER;
public R visit(BOOLEAN data) throws E {
return null;
}
-
+
/*
* (non-Javadoc)
*
*
* @see
* jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.BigINTEGER)
+ */
+ public R visit(BigINTEGER data) throws E {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
* .builtin.BIT_STRING)
*/
public R visit(BIT_STRING data) throws E {
public R visit(REAL data) throws E {
return null;
}
-
+
/*
* (non-Javadoc)
*
return null;
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
+ * .builtin.BigENUMERATED)
+ */
+ public R visit(BigENUMERATED data) throws E {
+ return null;
+ }
+
/* (non-Javadoc)
* @see jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type.builtin.RELATIVE_OID)
*/
System.out.println("Source data:");
System.out.println(frights);
derEncAndDec(frights);
- xerEncAndDec(frights);
+ xerEncAndDec(frights);
}
static void derEncAndDec(ASN1Type data) {
*/
package jp.bitmeister.asn1.sample;
-import java.math.BigInteger;
-
import jp.bitmeister.asn1.annotation.ASN1Alternative;
import jp.bitmeister.asn1.annotation.ASN1DefinedTypes;
import jp.bitmeister.asn1.annotation.ASN1Element;
public Airport() {
}
- public Airport(BigInteger value) {
+ public Airport(Integer value) {
super(value);
}
private void setTagMode(ASN1TagMode tagMode, ASN1TagDefault tagDefault,
Class<? extends ASN1Type> type, String fieldName) {
if (tagMode == ASN1TagMode.DEFAULT) {
- if (tagDefault == ASN1TagDefault.IMPLICIT_TAGS) {
+ if (tagDefault == ASN1TagDefault.IMPLICIT_TAGS
+ || (tagDefault == ASN1TagDefault.AUTOMATIC_TAGS && canImplicitTagging(type))) {
this.tagMode = ASN1TagMode.IMPLICIT;
} else {
this.tagMode = ASN1TagMode.EXPLICIT;
--- /dev/null
+/*
+ * Copyright 2011-2012 BitMeister Inc.
+ *
+ * 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 jp.bitmeister.asn1.type;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import jp.bitmeister.asn1.annotation.ASN1Enumeration;
+import jp.bitmeister.asn1.exception.ASN1IllegalArgument;
+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
+import jp.bitmeister.asn1.type.builtin.INTEGER;
+
+/**
+ * The base class for ASN.1 'INTEGER' types.
+ *
+ * <p>
+ * This class provides generic interfaces and common methods for classes that
+ * represents ASN.1 'INTEGER' type.
+ * </p>
+ * <p>
+ * A sub-class of {@code AbstractInteger} can contain one or more fields
+ * annotated as {@code @ASN1Enumeration}. If a sub-class of
+ * {@code AbstractInteger} contains {@code @ASN1Enumeration} fields, the value
+ * of the data must be same as one of the {@code @ASN1Enumeration} fields.
+ * </p>
+ *
+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
+ *
+ * @see ASN1Enumeration
+ * @see INTEGER
+ * @see BigINTEGER
+ */
+public abstract class AbstractInteger<T extends Number & Comparable<T>> extends
+ PrimitiveType<T> implements ValueComparable<AbstractInteger<T>> {
+
+ /**
+ * Sets the value specified by the name of number to this data.
+ *
+ * @param nameOfNumber
+ * The name of number.
+ */
+ public void set(String nameOfNumber) {
+ for (Entry<T, String> e : getNamedNumberMap().entrySet()) {
+ if (e.getValue().equals(nameOfNumber)) {
+ set(e.getKey());
+ return;
+ }
+ }
+ ASN1IllegalArgument e = new ASN1IllegalArgument();
+ e.setMessage("The name '" + nameOfNumber
+ + "' is not defined in this type.", null, getClass(), null,
+ null);
+ throw e;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see jp.bitmeister.asn1.type.PrimitiveType#set(null)
+ */
+ @Override
+ public void set(T value) {
+ if (isEnum()) {
+ Map<T, String> map = getNamedNumberMap();
+ if (!map.isEmpty() && !map.containsKey(value)) {
+ ASN1IllegalArgument ex = new ASN1IllegalArgument();
+ ex.setMessage(
+ "Invalid value '"
+ + value
+ + "'. Value of a class that represents ASN.1 'ENUMERATED' must be same as one of enumerations.",
+ null, getClass(), null, null);
+ throw ex;
+ }
+ }
+ super.set(value);
+ }
+
+ /**
+ * Returns an identifier related to the value of this data if the type has
+ * {@code @ASN1Enumeration} fields.
+ *
+ * @return An identifier related to the value.
+ */
+ public String identifier() {
+ return getNamedNumberMap().get(value());
+ }
+
+ /**
+ * Tests if the value of this data is in the range of {@code long} value.
+ *
+ * @return {@code true} when the value of this data is in the range of
+ * {@code long}.
+ */
+ public abstract boolean isLongValue();
+
+ /**
+ * Tests if the value of this data is in the range of {@code int} value.
+ *
+ * @return {@code true} when the value of this data is in the range of
+ * {@code int}.
+ */
+ public abstract boolean isIntValue();
+
+ /**
+ * Returns a {@code long} value that converted from the value of this data.
+ *
+ * @return A {@code long} value.
+ */
+ public long longValue() {
+ return value().longValue();
+ }
+
+ /**
+ * Returns an {@code int} value that converted from the value of this data.
+ *
+ * @return An {@code int} value.
+ */
+ public int intValue() {
+ return value().intValue();
+ }
+
+ /* (non-Javadoc)
+ * @see jp.bitmeister.asn1.type.ValueComparable#compareTo(jp.bitmeister.asn1.type.ASN1Type)
+ */
+ public int compareTo(AbstractInteger<T> other) {
+ return value().compareTo(other.value());
+ }
+
+ /**
+ * Returns map of enumerations related to this type.
+ *
+ * @return The map of enumerations.
+ */
+ protected abstract Map<T, String> getNamedNumberMap();
+
+ /**
+ * Tests if base type of this data is ASN.1 'ENUMERATED'.
+ *
+ * @return {@code true} if base type of this data is ASN.1 'ENUMERATED'.
+ */
+ protected abstract boolean isEnum();
+
+}
import jp.bitmeister.asn1.type.builtin.ANY;
import jp.bitmeister.asn1.type.builtin.BIT_STRING;
import jp.bitmeister.asn1.type.builtin.BOOLEAN;
-import jp.bitmeister.asn1.type.builtin.ENUMERATED;
-import jp.bitmeister.asn1.type.builtin.INTEGER;
+import jp.bitmeister.asn1.type.builtin.BigENUMERATED;
+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
import jp.bitmeister.asn1.type.builtin.NULL;
import jp.bitmeister.asn1.type.builtin.OBJECT_IDENTIFIER;
import jp.bitmeister.asn1.type.builtin.OCTET_STRING;
@ASN1ModuleTags(ASN1TagDefault.AUTOMATIC_TAGS)
@ASN1DefinedTypes({
BOOLEAN.class, // UNIVERSAL 1
- INTEGER.class, // UNIVERSAL 2
+ BigINTEGER.class, // UNIVERSAL 2
BIT_STRING.class, // UNIVERSAL 3
OCTET_STRING.class, // UNIVERSAL 4
NULL.class, // UNIVERSAL 5
*
* @author WATANABE, Jun. <jwat at bitmeister.jp>
*
- * @see ENUMERATED
- * @see INTEGER
+ * @see BigENUMERATED
+ * @see BigINTEGER
*/
@ASN1BuiltIn
@ASN1Identifier("ENUMERATED(unknown)")
@ASN1Tag(value = 10, tagClass = ASN1TagClass.UNIVERSAL, tagMode = ASN1TagMode.IMPLICIT)
- public static class UnknownEnumerated extends INTEGER {
+ public static class UnknownEnumerated extends BigINTEGER {
}
/**
--- /dev/null
+/*
+ * Copyright 2011-2012 BitMeister Inc.
+ *
+ * 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 jp.bitmeister.asn1.type;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+
+import jp.bitmeister.asn1.annotation.ASN1BuiltIn;
+import jp.bitmeister.asn1.annotation.ASN1Enumeration;
+import jp.bitmeister.asn1.annotation.ASN1Identifier;
+import jp.bitmeister.asn1.exception.ASN1IllegalDefinition;
+import jp.bitmeister.asn1.exception.ASN1RuntimeException;
+
+/**
+ * Contains values and identifiers of enumerations related to ASN.1 'INTEGER' and 'ENUMERATED' types.
+ *
+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
+ *
+ * @see AbstractInteger
+ */
+public abstract class NamedNumberMap<T extends Number & Comparable<T>> {
+
+ /**
+ * Map of maps of enumerations that related to key types.
+ */
+ private Map<Class<? extends AbstractInteger<T>>, Map<T, String>> namedNumberMaps = new HashMap<Class<? extends AbstractInteger<T>>, Map<T, String>>();
+
+ /**
+ * Put an empty enumeration map to {@code namedNumberMaps}.
+ *
+ * @param type The key type.
+ */
+ public void putEmptyMap(Class<? extends AbstractInteger<T>> type) {
+ namedNumberMaps.put(type, new HashMap<T, String>());
+ }
+
+ /**
+ * Returns the map of enumerations related to the type. The {@code Map} maps
+ * value to identifier string.
+ *
+ * @param type
+ * the Type.
+ * @return The map of enumerations.
+ */
+ public Map<T, String> getNamedNumberMap(Class<? extends AbstractInteger<T>> type) {
+ Map<T, String> map = namedNumberMaps.get(type);
+ if (map != null) {
+ return map;
+ }
+ map = new HashMap<T, String>();
+ for (Field f : type.getDeclaredFields()) {
+ if (!f.isAnnotationPresent(ASN1Enumeration.class)) {
+ continue;
+ }
+ final int modifier = Modifier.PUBLIC | Modifier.STATIC
+ | Modifier.FINAL;
+ ASN1Identifier id = f.getAnnotation(ASN1Identifier.class);
+ String fieldId = id != null ? id.value() : f.getName();
+ if ((f.getModifiers() & modifier) != modifier) {
+ ASN1IllegalDefinition ex = new ASN1IllegalDefinition();
+ ex.setMessage(
+ "An enumeration must be a public static final field.",
+ null, type, fieldId, null);
+ throw ex;
+ }
+ T value = null;
+ try {
+ value = getKeyValue(f);
+ }
+ catch (ASN1RuntimeException ex) {
+ ex.setMessage(ex.getMessage(), ex.getCause(), type, fieldId, null);
+ throw ex;
+ }
+ if (map.containsKey(value)) {
+ ASN1IllegalDefinition ex = new ASN1IllegalDefinition();
+ ex.setMessage(
+ "Each number of enumerations shall be distinct from all other enumerations in the type.",
+ null, type, fieldId, null);
+ throw ex;
+ }
+ map.put(value, fieldId);
+ }
+ @SuppressWarnings("unchecked")
+ Class<? extends AbstractInteger<T>> parent = (Class<? extends AbstractInteger<T>>)type.getSuperclass();
+ if (parent.isAnnotationPresent(ASN1BuiltIn.class)) {
+ if (!type.getSuperclass().equals(AbstractInteger.class) && map.isEmpty()) {
+ ASN1IllegalDefinition ex = new ASN1IllegalDefinition();
+ ex.setMessage(
+ "ENUMERATED type shall have at least one enumeration item.",
+ null, type, null, null);
+ throw ex;
+ }
+ }
+ else {
+ if (!map.isEmpty()) {
+ ASN1IllegalDefinition ex = new ASN1IllegalDefinition();
+ ex.setMessage(
+ "A class that does not extend 'INTEGER' or 'ENUMERATED' directly, can not have own enumerations.",
+ null, type, null, null);
+ throw ex;
+ }
+ map = getNamedNumberMap(parent);
+ }
+ namedNumberMaps.put(type, map);
+ return map;
+ }
+
+ /**
+ * Returns key value that defined by the enumeration field.
+ *
+ * @param f
+ * The enumeration field.
+ * @return The key value.
+ */
+ public abstract T getKeyValue(Field f);
+
+}
*/
package jp.bitmeister.asn1.type;
+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
import jp.bitmeister.asn1.type.builtin.INTEGER;
import jp.bitmeister.asn1.type.builtin.REAL;
* The interface for classes whose instance can be compared to other instance.
*
* <p>
- * {@code INTEGER} and {@code REAL} implements this interface and their value
- * shall be ordered by the natural ordering. {@code compareTo} method is used
- * for compare the value to the other value.
+ * {@code INTEGER}, {@code BigINTEGER} and {@code REAL} implements this
+ * interface and their value shall be ordered by the natural ordering.
+ * {@code compareTo} method is used for compare the value to the other value.
* </p>
*
* @author WATANABE, Jun. <jwat at bitmeister.jp>
*
* @see INTEGER
+ * @see BigINTEGER
* @see REAL
*/
-public interface ValueComparable {
+public interface ValueComparable<T extends ASN1Type> {
/**
* Compares the value of this instance to the value of the other instance.
* @return A negative integer, zero, or a positive integer as this value is
* less than, equal to, or greater than the other value.
*/
- public int compareTo(ASN1Type other);
+ public int compareTo(T other);
}
--- /dev/null
+/*
+ * Copyright 2011-2012 BitMeister Inc.
+ *
+ * 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 jp.bitmeister.asn1.type.builtin;
+
+import java.math.BigInteger;
+
+import jp.bitmeister.asn1.annotation.ASN1BuiltIn;
+import jp.bitmeister.asn1.annotation.ASN1Enumeration;
+import jp.bitmeister.asn1.annotation.ASN1Identifier;
+import jp.bitmeister.asn1.annotation.ASN1Tag;
+import jp.bitmeister.asn1.processor.ASN1Visitor;
+import jp.bitmeister.asn1.type.ASN1TagClass;
+import jp.bitmeister.asn1.type.ASN1TagMode;
+
+/**
+ * An implementation of ASN.1 'ENUMERATED' type that can contain
+ * arbitrary-precision integer value.
+ *
+ * <p>
+ * This is the base class used for defining 'ENUMERATED' types which need to
+ * contain an arbitrary-precision value. A sub-class of {@code BigENUMERATED}
+ * must contain one or more fields annotated as {@code @ASN1Enumeration}.
+ * </p>
+ *
+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
+ *
+ * @see ASN1Enumeration
+ * @see ENUMERATED
+ */
+@ASN1BuiltIn
+@ASN1Identifier("ENUMERATED")
+@ASN1Tag(tagClass = ASN1TagClass.UNIVERSAL, value = 10, tagMode = ASN1TagMode.IMPLICIT)
+public abstract class BigENUMERATED extends BigINTEGER {
+
+ /**
+ * Instantiates an empty {@code BigENUMERATED}.
+ */
+ public BigENUMERATED() {
+ }
+
+ /**
+ * Instantiates an {@code BigENUMERATED} and initialize it with the
+ * {@code BigInteger} value.
+ *
+ * @param value
+ * The value to be assigned.
+ */
+ public BigENUMERATED(BigInteger value) {
+ super(value);
+ }
+
+ /**
+ * Instantiates an {@code BigENUMERATED} and initialize it with the {@code long}
+ * value.
+ *
+ * @param value
+ * The value to be assigned.
+ */
+ public BigENUMERATED(long value) {
+ super(value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.type.builtin.INTEGER#accept(jp.bitmeister.asn1.processor
+ * .ASN1Visitor)
+ */
+ @Override
+ public <R, E extends Throwable> R accept(ASN1Visitor<R, E> visitor) throws E {
+ return visitor.visit(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see jp.bitmeister.asn1.type.AbstractInteger#isEnum()
+ */
+ @Override
+ protected boolean isEnum() {
+ return true;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2011-2012 BitMeister Inc.
+ *
+ * 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 jp.bitmeister.asn1.type.builtin;
+
+import java.lang.reflect.Field;
+import java.math.BigInteger;
+import java.util.Map;
+
+import jp.bitmeister.asn1.annotation.ASN1BuiltIn;
+import jp.bitmeister.asn1.annotation.ASN1Identifier;
+import jp.bitmeister.asn1.annotation.ASN1Tag;
+import jp.bitmeister.asn1.exception.ASN1IllegalDefinition;
+import jp.bitmeister.asn1.exception.ASN1RuntimeException;
+import jp.bitmeister.asn1.processor.ASN1Visitor;
+import jp.bitmeister.asn1.type.ASN1TagClass;
+import jp.bitmeister.asn1.type.ASN1TagMode;
+import jp.bitmeister.asn1.type.AbstractInteger;
+import jp.bitmeister.asn1.type.NamedNumberMap;
+
+/**
+ * An implementation of ASN.1 'INTEGER' type that can contain
+ * arbitrary-precision integer value.
+ *
+ * <p>
+ * An instance of this class represents an 'INTEGER' type data that needs to
+ * contain an arbitrary-precision value. It has a {@link java.math.BigInteger}
+ * value.
+ * </p>
+ *
+ * @author WATANABE, Jun. <jwat at bitmeister.jp>
+ *
+ * @see INTEGER
+ */
+@ASN1BuiltIn
+@ASN1Identifier("INTEGER")
+@ASN1Tag(tagClass = ASN1TagClass.UNIVERSAL, value = 2, tagMode = ASN1TagMode.IMPLICIT)
+public class BigINTEGER extends AbstractInteger<BigInteger> {
+
+ /**
+ * Contains the maps of enumerations for all of the sub-types of {@code BigINTEGER}
+ * and {@code BigENUMERATED}.
+ */
+ private static final NamedNumberMap<BigInteger> NAMED_NUMBER_MAPS = new NamedNumberMap<BigInteger>() {
+
+ /* (non-Javadoc)
+ * @see jp.bitmeister.asn1.type.NamedNumberMap#getKeyValue(java.lang.reflect.Field)
+ */
+ @Override
+ public BigInteger getKeyValue(Field f) {
+ BigInteger value;
+ if (f.getType() == BigInteger.class) {
+ try {
+ value = (BigInteger) f.get(null);
+ } catch (Exception e) {
+ ASN1RuntimeException ex = new ASN1RuntimeException(
+ "Failed to retreave the BigInteger value.");
+ throw ex;
+ }
+ } else if (f.getType() == int.class || f.getType() == long.class) {
+ try {
+ value = BigInteger.valueOf(f.getLong(null));
+ } catch (Exception e) {
+ ASN1RuntimeException ex = new ASN1RuntimeException(
+ "Failed to convert the value to BigInteger.");
+ throw ex;
+ }
+ } else {
+ ASN1IllegalDefinition ex = new ASN1IllegalDefinition(
+ "An enumeration of BigINTEGER type must be an 'int', a 'long' or a 'BigInteger' field.");
+ throw ex;
+ }
+ return value;
+ }
+
+ };
+
+ static {
+ NAMED_NUMBER_MAPS.putEmptyMap(BigINTEGER.class);
+ }
+
+ /**
+ * Instantiates an empty {@code INTEGER}.
+ */
+ public BigINTEGER() {
+ }
+
+ /**
+ * Instantiates an {@code INTEGER} and initialize it with the
+ * {@code BigInteger} value.
+ *
+ * @param value
+ * The value to be assigned.
+ */
+ public BigINTEGER(BigInteger value) {
+ set(value);
+ }
+
+ /**
+ * Instantiates an {@code INTEGER} and initialize it with the {@code long}
+ * value.
+ *
+ * @param value
+ * The value to be assigned.
+ */
+ public BigINTEGER(long value) {
+ set(value);
+ }
+
+ /**
+ * Sets the {@code long} value to this data.
+ *
+ * @param value
+ * The value to be assigned.
+ */
+ public void set(long value) {
+ set(BigInteger.valueOf(value));
+ }
+
+ /**
+ * Tests if the value of this data is in the range of {@code long} value.
+ *
+ * @return {@code true} when the value of this data is in the range of
+ * {@code long}.
+ */
+ public boolean isLongValue() {
+ return value().compareTo(BigInteger.valueOf(Long.MIN_VALUE)) >= 0
+ && value().compareTo(BigInteger.valueOf(Long.MAX_VALUE)) <= 0;
+ }
+
+ /**
+ * Tests if the value of this data is in the range of {@code int} value.
+ *
+ * @return {@code true} when the value of this data is in the range of
+ * {@code int}.
+ */
+ public boolean isIntValue() {
+ return value().compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) >= 0
+ && value().compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) <= 0;
+ }
+
+
+ /* (non-Javadoc)
+ * @see jp.bitmeister.asn1.type.AbstractInteger#getNamedNumberMap()
+ */
+ @Override
+ public Map<BigInteger, String> getNamedNumberMap() {
+ return NAMED_NUMBER_MAPS.getNamedNumberMap(getClass());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jp.bitmeister.asn1.type.ASN1Type#accept(jp.bitmeister.asn1.processor.
+ * ASN1Visitor)
+ */
+ @Override
+ public <R, E extends Throwable> R accept(ASN1Visitor<R, E> visitor) throws E {
+ return visitor.visit(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see jp.bitmeister.asn1.type.AbstractInteger#isEnum()
+ */
+ @Override
+ protected boolean isEnum() {
+ return false;
+ }
+
+}
/**
* Instantiates a {@code CHOICE} and initialize it with the parameter. The
- * ASN.1 tag that assigned to the type of the data is used for select an
- * alternative.
+ * ASN.1 type of the data is used for select an alternative.
*
* @param data
* The data to be assigned.
*/
package jp.bitmeister.asn1.type.builtin;
-import java.math.BigInteger;
-
import jp.bitmeister.asn1.annotation.ASN1BuiltIn;
import jp.bitmeister.asn1.annotation.ASN1Enumeration;
import jp.bitmeister.asn1.annotation.ASN1Tag;
import jp.bitmeister.asn1.type.ASN1TagMode;
/**
- * Represents ASN.1 'ENUMERATED' type.
+ * An implementation of ASN.1 'ENUMERATED' type that contains {@code Long}
+ * value.
*
* <p>
- * This is the base class used for defining 'ENUMERATED' types. A sub-class of
- * {@code ENUMERATED} must contain one or more fields annotated as
- * {@code @ASN1Enumeration}.
+ * This is the base class used for defining 'ENUMERATED' types, and has a
+ * {@link java.lang.Long} value. If the data needs to contain value which is
+ * bigger than {@code Long.MAX_VALUE} or smaller than {@code Long.MIN_VALUE},
+ * {@code BigENUMERATED} type shall be used. A sub-class of {@code ENUMERATED}
+ * must contain one or more fields annotated as {@code @ASN1Enumeration}.
* </p>
*
* @author WATANABE, Jun. <jwat at bitmeister.jp>
*
* @see ASN1Enumeration
+ * @see BigENUMERATED
*/
@ASN1BuiltIn
@ASN1Tag(tagClass = ASN1TagClass.UNIVERSAL, value = 10, tagMode = ASN1TagMode.IMPLICIT)
}
/**
- * Instantiates an {@code ENUMERATED} and initialize it with the
- * {@code BigInteger} value.
- *
- * @param value
- * The value to be assigned.
- */
- public ENUMERATED(BigInteger value) {
- super(value);
- }
-
- /**
* Instantiates an {@code ENUMERATED} and initialize it with the {@code long}
* value.
*
return visitor.visit(this);
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see jp.bitmeister.asn1.type.AbstractInteger#isEnum()
+ */
+ @Override
+ protected boolean isEnum() {
+ return true;
+ }
+
}
-/*
- * Copyright 2011-2012 BitMeister Inc.
- *
- * 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 jp.bitmeister.asn1.type.builtin;
import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.math.BigInteger;
-import java.util.HashMap;
import java.util.Map;
-import java.util.Map.Entry;
import jp.bitmeister.asn1.annotation.ASN1BuiltIn;
-import jp.bitmeister.asn1.annotation.ASN1Enumeration;
-import jp.bitmeister.asn1.annotation.ASN1Identifier;
import jp.bitmeister.asn1.annotation.ASN1Tag;
-import jp.bitmeister.asn1.exception.ASN1IllegalArgument;
import jp.bitmeister.asn1.exception.ASN1IllegalDefinition;
import jp.bitmeister.asn1.exception.ASN1RuntimeException;
import jp.bitmeister.asn1.processor.ASN1Visitor;
import jp.bitmeister.asn1.type.ASN1TagClass;
import jp.bitmeister.asn1.type.ASN1TagMode;
-import jp.bitmeister.asn1.type.ASN1Type;
-import jp.bitmeister.asn1.type.PrimitiveType;
-import jp.bitmeister.asn1.type.ValueComparable;
+import jp.bitmeister.asn1.type.AbstractInteger;
+import jp.bitmeister.asn1.type.NamedNumberMap;
/**
- * Represents ASN.1 'INTEGER' type.
+ * An implementation of ASN.1 'INTEGER' type that contains {@code Long} value.
*
* <p>
* An instance of this class represents an 'INTEGER' type data, and has a
- * {@link java.math.BigInteger} value.
- * </p>
- * <p>
- * A sub-class of {@code INTEGER} can contain one or more fields annotated as
- * {@code @ASN1Enumeration}. If a sub-class of {@code INTEGER} contains
- * {@code @ASN1Enumeration} fields, the value of the data must be same as one of
- * the {@code @ASN1Enumeration} fields.
+ * {@link java.lang.Long} value. If the data needs to contain value which is
+ * bigger than {@code Long.MAX_VALUE} or smaller than {@code Long.MIN_VALUE},
+ * {@code BigINTEGER} type shall be used.
* </p>
*
* @author WATANABE, Jun. <jwat at bitmeister.jp>
*
- * @see ASN1Enumeration
+ * @see BigINTEGER
*/
@ASN1BuiltIn
@ASN1Tag(tagClass = ASN1TagClass.UNIVERSAL, value = 2, tagMode = ASN1TagMode.IMPLICIT)
-public class INTEGER extends PrimitiveType<BigInteger> implements
- ValueComparable {
+public class INTEGER extends AbstractInteger<Long> {
/**
- * Contains the maps of enumerations for all of the sub-types of 'INTEGER'
- * and 'ENUMERATED'.
+ * Contains the maps of enumerations for all of the sub-types of {@code INTEGER}
+ * and {@code ENUMERATED}.
*/
- private static final Map<Class<? extends INTEGER>, Map<BigInteger, String>> NAMED_NUMBER_MAPS = new HashMap<Class<? extends INTEGER>, Map<BigInteger, String>>();
-
- static {
- NAMED_NUMBER_MAPS.put(INTEGER.class, new HashMap<BigInteger, String>());
- }
+ private static final NamedNumberMap<Long> NAMED_NUMBER_MAPS = new NamedNumberMap<Long>() {
- /**
- * Returns the map of enumerations for the type. The {@code Map} maps value
- * to identifier.
- *
- * @param type
- * The type.
- * @return The map of enumerations.
- */
- private static Map<BigInteger, String> getNamedNumberMap(
- Class<? extends INTEGER> type) {
- if (NAMED_NUMBER_MAPS.containsKey(type)) {
- return NAMED_NUMBER_MAPS.get(type);
- }
- Map<BigInteger, String> map = new HashMap<BigInteger, String>();
- for (Field f : type.getDeclaredFields()) {
- if (!f.isAnnotationPresent(ASN1Enumeration.class)) {
- continue;
- }
- final int modifier = Modifier.PUBLIC | Modifier.STATIC
- | Modifier.FINAL;
- ASN1Identifier id = f.getAnnotation(ASN1Identifier.class);
- String fieldId = id != null ? id.value() : f.getName();
- if ((f.getModifiers() & modifier) != modifier) {
- ASN1IllegalDefinition ex = new ASN1IllegalDefinition();
- ex.setMessage(
- "An enumeration must be a public static final field.",
- null, type, fieldId, null);
- throw ex;
- }
- BigInteger value;
- if (f.getType() == BigInteger.class) {
- try {
- value = (BigInteger) f.get(null);
- } catch (Exception e) {
- ASN1RuntimeException ex = new ASN1RuntimeException();
- ex.setMessage("Failed to retreave the BigInteger value.",
- e, type, fieldId, null);
- throw ex;
- }
- } else if (f.getType() == int.class || f.getType() == long.class) {
+ @Override
+ public Long getKeyValue(Field f) {
+ Long value;
+ if (f.getType() == int.class || f.getType() == long.class) {
try {
- value = BigInteger.valueOf(f.getLong(null));
+ value = f.getLong(null);
} catch (Exception e) {
- ASN1RuntimeException ex = new ASN1RuntimeException();
- ex.setMessage("Failed to convert the value to BigInteger.",
- e, type, fieldId, null);
+ ASN1RuntimeException ex = new ASN1RuntimeException(
+ "Failed to retreave the Long value.");
throw ex;
}
} else {
- ASN1IllegalDefinition ex = new ASN1IllegalDefinition();
- ex.setMessage(
- "An enumeration must be an 'int', 'long' or 'BigInteger' field.",
- null, type, fieldId, null);
- throw ex;
- }
- if (map.containsKey(value)) {
- ASN1IllegalDefinition ex = new ASN1IllegalDefinition();
- ex.setMessage(
- "Each number of enumerations shall be distinct from all other enumerations in the type.",
- null, type, fieldId, null);
- throw ex;
- }
- map.put(value, fieldId);
- }
- Class<? extends INTEGER> parent = type.getSuperclass().asSubclass(INTEGER.class);
- if (parent == ENUMERATED.class) {
- if (map.isEmpty()) {
- ASN1IllegalDefinition ex = new ASN1IllegalDefinition();
- ex.setMessage(
- "ENUMERATED type shall have at least one enumeration item.",
- null, type, null, null);
+ ASN1IllegalDefinition ex = new ASN1IllegalDefinition(
+ "An enumeration of INTEGER type must be an 'int' or a 'long' field.");
throw ex;
}
- } else if (parent != INTEGER.class) {
- if (!map.isEmpty()) {
- ASN1IllegalDefinition ex = new ASN1IllegalDefinition();
- ex.setMessage(
- "A class that does not extend 'INTEGER' or 'ENUMERATED' directly, can not have own enumerations.",
- null, type, null, null);
- throw ex;
- }
- map = getNamedNumberMap(parent);
+ return value;
}
- NAMED_NUMBER_MAPS.put(type, map);
- return map;
+
+ };
+
+ static {
+ NAMED_NUMBER_MAPS.putEmptyMap(INTEGER.class);
}
/**
}
/**
- * Instantiates an {@code INTEGER} and initialize it with the
- * {@code BigInteger} value.
- *
- * @param value
- * The value to be assigned.
- */
- public INTEGER(BigInteger value) {
- set(value);
- }
-
- /**
* Instantiates an {@code INTEGER} and initialize it with the {@code long}
* value.
*
set(value);
}
- /*
- * (non-Javadoc)
- *
- * @see jp.bitmeister.asn1.type.PrimitiveType#set(null)
+ /* (non-Javadoc)
+ * @see jp.bitmeister.asn1.type.AbstractInteger#getNamedNumberMap()
*/
@Override
- public void set(BigInteger value) {
- Map<BigInteger, String> map = getNamedNumberMap(getClass());
- if (!map.isEmpty() && !map.containsKey(value)) {
- ASN1IllegalArgument ex = new ASN1IllegalArgument();
- ex.setMessage(
- "Invalid value '"
- + value
- + "'. If a class has enumerations, the value must be same as one of them.",
- null, getClass(), null, null);
- throw ex;
- }
- super.set(value);
- }
-
- /**
- * Sets the {@code long} value to this data.
- *
- * @param value
- * The value to be assigned.
- */
- public void set(long value) {
- set(BigInteger.valueOf(value));
- }
-
- /**
- * Sets the value specified by the name of number to this data.
- *
- * @param nameOfNumber
- * The name of number.
- */
- public void set(String nameOfNumber) {
- for (Entry<BigInteger, String> e: getNamedNumberMap(getClass()).entrySet()) {
- if (e.getValue().equals(nameOfNumber)) {
- set(e.getKey());
- return;
- }
- }
- ASN1IllegalArgument e = new ASN1IllegalArgument();
- e.setMessage("The name '" + nameOfNumber + "' is not defined in this type.", null, getClass(), null, null);
- throw e;
+ public Map<Long, String> getNamedNumberMap() {
+ return NAMED_NUMBER_MAPS.getNamedNumberMap(getClass());
}
- /**
- * Returns an identifier related to the value of this data if the type has
- * {@code @ASN1Enumeration} fields.
- *
- * @return An identifier related to the value.
+ /* (non-Javadoc)
+ * @see jp.bitmeister.asn1.type.ASN1Type#accept(jp.bitmeister.asn1.processor.ASN1Visitor)
*/
- public String identifier() {
- return getNamedNumberMap(getClass()).get(value());
+ @Override
+ public <R, E extends Throwable> R accept(ASN1Visitor<R, E> visitor)
+ throws E {
+ return visitor.visit(this);
}
- /**
- * Tests if the value of this data is in the range of {@code long} value.
- *
- * @return {@code true} when the value of this data is in the range of
- * {@code long}.
+ /* (non-Javadoc)
+ * @see jp.bitmeister.asn1.type.AbstractInteger#isLongValue()
*/
+ @Override
public boolean isLongValue() {
- return value().compareTo(BigInteger.valueOf(Long.MIN_VALUE)) >= 0
- && value().compareTo(BigInteger.valueOf(Long.MAX_VALUE)) <= 0;
+ return true;
}
- /**
- * Tests if the value of this data is in the range of {@code int} value.
- *
- * @return {@code true} when the value of this data is in the range of
- * {@code int}.
+ /* (non-Javadoc)
+ * @see jp.bitmeister.asn1.type.AbstractInteger#isIntValue()
*/
+ @Override
public boolean isIntValue() {
- return value().compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) >= 0
- && value().compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) <= 0;
- }
-
- /**
- * Returns a {@code long} value that converted from the value of this data.
- *
- * @return A {@code long} value.
- */
- public long longValue() {
- return value().longValue();
- }
-
- /**
- * Returns an {@code int} value that converted from the value of this data.
- *
- * @return An {@code int} value.
- */
- public int intValue() {
- return value().intValue();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * jp.bitmeister.asn1.type.ValueComparable#compareTo(jp.bitmeister.asn1.
- * type.ASN1Type)
- */
- public int compareTo(ASN1Type other) {
- return value().compareTo(((INTEGER) other).value());
+ return Integer.MIN_VALUE <= value() && value() <= Integer.MAX_VALUE;
}
-
+
/*
* (non-Javadoc)
*
- * @see
- * jp.bitmeister.asn1.type.ASN1Type#accept(jp.bitmeister.asn1.processor.
- * ASN1Visitor)
+ * @see jp.bitmeister.asn1.type.AbstractInteger#isEnum()
*/
@Override
- public <R, E extends Throwable> R accept(ASN1Visitor<R, E> visitor) throws E {
- return visitor.visit(this);
+ protected boolean isEnum() {
+ return false;
}
}
import jp.bitmeister.asn1.processor.ASN1Visitor;
import jp.bitmeister.asn1.type.ASN1TagClass;
import jp.bitmeister.asn1.type.ASN1TagMode;
-import jp.bitmeister.asn1.type.ASN1Type;
import jp.bitmeister.asn1.type.PrimitiveType;
import jp.bitmeister.asn1.type.ValueComparable;
*/
@ASN1BuiltIn
@ASN1Tag(tagClass = ASN1TagClass.UNIVERSAL, value = 9, tagMode = ASN1TagMode.IMPLICIT)
-public class REAL extends PrimitiveType<Double> implements ValueComparable {
+public class REAL extends PrimitiveType<Double> implements ValueComparable<REAL> {
private boolean isBinary = false;
* jp.bitmeister.asn1.type.ValueComparable#compareTo(jp.bitmeister.asn1.
* type.ASN1Type)
*/
- public int compareTo(ASN1Type other) {
- return value().compareTo(((REAL) other).value());
+ public int compareTo(REAL other) {
+ return value().compareTo(other.value());
}
/*
import jp.bitmeister.asn1.type.ASN1TagMode;
import jp.bitmeister.asn1.type.ASN1Type;
import jp.bitmeister.asn1.type.builtin.CHOICE;
-import jp.bitmeister.asn1.type.builtin.INTEGER;
+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
import jp.bitmeister.asn1.type.builtin.NULL;
import jp.bitmeister.asn1.type.builtin.OBJECT_IDENTIFIER;
import jp.bitmeister.asn1.type.builtin.OCTET_STRING;
*/
@ASN1Element(0)
@ASN1Identifier("presentation-context-id")
- public INTEGER presentation_context_id;
+ public BigINTEGER presentation_context_id;
/**
* 'transfer-syntax' field.
* @param transfer_syntax
* 'transfer-syntax' field.
*/
- public ContextNegotiation(INTEGER presentation_context_id,
+ public ContextNegotiation(BigINTEGER presentation_context_id,
OBJECT_IDENTIFIER transfer_syntax) {
this.presentation_context_id = presentation_context_id;
this.transfer_syntax = transfer_syntax;
*/
@ASN1Alternative(2)
@ASN1Identifier("presentation-context-id")
- public INTEGER presentation_context_id;
+ public BigINTEGER presentation_context_id;
/**
* 'context-negotiation' field.
import jp.bitmeister.asn1.type.builtin.ANY;
import jp.bitmeister.asn1.type.builtin.BIT_STRING;
import jp.bitmeister.asn1.type.builtin.CHOICE;
-import jp.bitmeister.asn1.type.builtin.INTEGER;
+import jp.bitmeister.asn1.type.builtin.BigINTEGER;
import jp.bitmeister.asn1.type.builtin.OBJECT_IDENTIFIER;
import jp.bitmeister.asn1.type.builtin.OCTET_STRING;
import jp.bitmeister.asn1.type.builtin.SEQUENCE;
*/
@ASN1Element(value = 1, optional = true)
@ASN1Identifier("indirect-reference")
- public INTEGER indirect_reference;
+ public BigINTEGER indirect_reference;
/**
* 'data-value-descriptor' field.
}
public EXTERNAL(OBJECT_IDENTIFIER direct_reference,
- INTEGER indirect_reference, ObjectDescriptor data_value_descriptor,
+ BigINTEGER indirect_reference, ObjectDescriptor data_value_descriptor,
Encoding encoding) {
this.direct_reference = direct_reference;
this.indirect_reference = indirect_reference;