/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* @author Vladimir N. Molotkov, Stepan M. Mishura
* @version $Revision$
*/
package org.apache.harmony.security.asn1;
/**
* Encodes ASN.1 types with BER (X.690)
*
* @see <a href="http://asn1.elibel.tm.fr/en/standards/index.htm">ASN.1</a>
*/
public class BerOutputStream {
/** Encoded byte array */
public byte[] encoded;
/** current offset */
protected int offset;
/** Current encoded length */
public int length;
/** Current encoded content */
public Object content;
public final void encodeTag(int tag) {
encoded[offset++] = (byte) tag; //FIXME long form?
if (length > 127) { //long form
int eLen = length >> 8;
byte numOctets = 1;
for (; eLen > 0; eLen = eLen >> 8) {
numOctets++;
}
encoded[offset] = (byte) (numOctets | 0x80);
offset++;
eLen = length;
int numOffset = offset + numOctets - 1;
for (int i = 0; i < numOctets; i++, eLen = eLen >> 8) {
encoded[numOffset - i] = (byte) eLen; //FIXME long value?
}
offset += numOctets;
} else { //short form
encoded[offset++] = (byte) length;
}
}
public void encodeANY() {
System.arraycopy(content, 0, encoded, offset, length);
offset += length;
}
public void encodeBitString() {
//FIXME check encoding
BitString bStr = (BitString) content;
encoded[offset] = (byte) bStr.unusedBits;
System.arraycopy(bStr.bytes, 0, encoded, offset + 1, length - 1);
offset += length;
}
public void encodeBoolean() {
if ((Boolean) content) {
encoded[offset] = (byte) 0xFF;
} else {
encoded[offset] = 0x00;
}
offset++;
}
public void encodeChoice(ASN1Choice choice) {
throw new RuntimeException("Is not implemented yet"); //FIXME
}
public void encodeExplicit(ASN1Explicit explicit) {
throw new RuntimeException("Is not implemented yet"); //FIXME
}
public void encodeGeneralizedTime() {
System.arraycopy(content, 0, encoded, offset, length);
offset += length;
}
public void encodeUTCTime() {
System.arraycopy(content, 0, encoded, offset, length);
offset += length;
}
public void encodeInteger() {
System.arraycopy(content, 0, encoded, offset, length);
offset += length;
}
public void encodeOctetString() {
System.arraycopy(content, 0, encoded, offset, length);
offset += length;
}
public void encodeOID() {
int[] oid = (int[]) content;
int oidLen = length;
// all subidentifiers except first
int elem;
for (int i = oid.length - 1; i > 1; i--, oidLen--) {
elem = oid[i];
if (elem > 127) {
encoded[offset + oidLen - 1] = (byte) (elem & 0x7F);
elem = elem >> 7;
for (; elem > 0;) {
oidLen--;
encoded[offset + oidLen - 1] = (byte) (elem | 0x80);
elem = elem >> 7;
}
} else {
encoded[offset + oidLen - 1] = (byte) elem;
}
}
// first subidentifier
elem = oid[0] * 40 + oid[1];
if (elem > 127) {
encoded[offset + oidLen - 1] = (byte) (elem & 0x7F);
elem = elem >> 7;
for (; elem > 0;) {
oidLen--;
encoded[offset + oidLen - 1] = (byte) (elem | 0x80);
elem = elem >> 7;
}
} else {
encoded[offset + oidLen - 1] = (byte) elem;
}
offset += length;
}
public void encodeSequence(ASN1Sequence sequence) {
throw new RuntimeException("Is not implemented yet"); //FIXME
}
public void encodeSequenceOf(ASN1SequenceOf sequenceOf) {
throw new RuntimeException("Is not implemented yet"); //FIXME
}
public void encodeSet(ASN1Set set) {
throw new RuntimeException("Is not implemented yet"); //FIXME
}
public void encodeSetOf(ASN1SetOf setOf) {
throw new RuntimeException("Is not implemented yet"); //FIXME
}
public void encodeString() {
System.arraycopy(content, 0, encoded, offset, length);
offset += length;
}
public void getChoiceLength(ASN1Choice choice) {
throw new RuntimeException("Is not implemented yet"); //FIXME
}
public void getExplicitLength(ASN1Explicit sequence) {
throw new RuntimeException("Is not implemented yet"); //FIXME
}
public void getSequenceLength(ASN1Sequence sequence) {
throw new RuntimeException("Is not implemented yet"); //FIXME
}
public void getSequenceOfLength(ASN1SequenceOf sequence) {
throw new RuntimeException("Is not implemented yet"); //FIXME
}
public void getSetLength(ASN1Set set) {
throw new RuntimeException("Is not implemented yet"); //FIXME
}
public void getSetOfLength(ASN1SetOf setOf) {
throw new RuntimeException("Is not implemented yet"); //FIXME
}
}