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