001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2006-2008 Sun Microsystems, Inc. 015 * Portions copyright 2012-2016 ForgeRock AS. 016 * Portions Copyright 2014 Manuel Gaupp 017 */ 018 019package org.forgerock.opendj.io; 020 021import static com.forgerock.opendj.ldap.CoreMessages.ERR_ASN1_UNEXPECTED_TAG; 022 023import java.io.IOException; 024 025import org.forgerock.i18n.LocalizableMessage; 026import org.forgerock.opendj.ldap.ByteString; 027import org.forgerock.opendj.ldap.ByteStringBuilder; 028import org.forgerock.opendj.ldap.DecodeException; 029 030/** 031 * An abstract {@code ASN1Reader} which can be used as the basis for 032 * implementing new ASN1 reader implementations. 033 */ 034public abstract class AbstractASN1Reader implements ASN1Reader { 035 /** Creates a new abstract ASN.1 reader. */ 036 protected AbstractASN1Reader() { 037 // No implementation required. 038 } 039 040 @Override 041 public boolean readBoolean(byte type) throws IOException { 042 if (type == 0x00) { 043 type = ASN1.UNIVERSAL_BOOLEAN_TYPE; 044 } 045 checkType(type); 046 return readBoolean(); 047 } 048 049 @Override 050 public int readEnumerated(byte type) throws IOException { 051 if (type == 0x00) { 052 type = ASN1.UNIVERSAL_ENUMERATED_TYPE; 053 } 054 checkType(type); 055 return readEnumerated(); 056 } 057 058 @Override 059 public long readInteger(byte type) throws IOException { 060 if (type == 0x00) { 061 type = ASN1.UNIVERSAL_INTEGER_TYPE; 062 } 063 checkType(type); 064 return readInteger(); 065 } 066 067 @Override 068 public void readNull(byte type) throws IOException { 069 if (type == 0x00) { 070 type = ASN1.UNIVERSAL_NULL_TYPE; 071 } 072 checkType(type); 073 readNull(); 074 } 075 076 @Override 077 public ByteString readOctetString(byte type) throws IOException { 078 if (type == 0x00) { 079 type = ASN1.UNIVERSAL_OCTET_STRING_TYPE; 080 } 081 checkType(type); 082 return readOctetString(); 083 } 084 085 @Override 086 public ByteStringBuilder readOctetString(byte type, final ByteStringBuilder builder) 087 throws IOException { 088 if (type == 0x00) { 089 type = ASN1.UNIVERSAL_OCTET_STRING_TYPE; 090 } 091 checkType(type); 092 readOctetString(builder); 093 return builder; 094 } 095 096 @Override 097 public String readOctetStringAsString(byte type) throws IOException { 098 // We could cache the UTF-8 CharSet if performance proves to be an 099 // issue. 100 if (type == 0x00) { 101 type = ASN1.UNIVERSAL_OCTET_STRING_TYPE; 102 } 103 checkType(type); 104 return readOctetStringAsString(); 105 } 106 107 @Override 108 public void readStartExplicitTag(byte type) throws IOException { 109 if (type == 0x00) { 110 type = (ASN1.TYPE_MASK_CONTEXT | ASN1.TYPE_MASK_CONSTRUCTED); 111 } 112 checkType(type); 113 readStartExplicitTag(); 114 } 115 116 @Override 117 public void readStartSequence(byte type) throws IOException { 118 if (type == 0x00) { 119 type = ASN1.UNIVERSAL_SEQUENCE_TYPE; 120 } 121 checkType(type); 122 readStartSequence(); 123 } 124 125 @Override 126 public void readStartSet(byte type) throws IOException { 127 // From an implementation point of view, a set is equivalent to a 128 // sequence. 129 if (type == 0x00) { 130 type = ASN1.UNIVERSAL_SET_TYPE; 131 } 132 checkType(type); 133 readStartSet(); 134 } 135 136 @Override 137 public ASN1Reader skipElement(final byte expectedType) throws IOException { 138 if (peekType() != expectedType) { 139 final LocalizableMessage message = 140 ERR_ASN1_UNEXPECTED_TAG.get(expectedType, peekType()); 141 throw DecodeException.fatalError(message); 142 } 143 skipElement(); 144 return this; 145 } 146 147 private void checkType(final byte expectedType) throws IOException { 148 if (peekType() != expectedType) { 149 final LocalizableMessage message = 150 ERR_ASN1_UNEXPECTED_TAG.get(expectedType, peekType()); 151 throw DecodeException.fatalError(message); 152 } 153 } 154}