⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 beroutputstream.java

📁 ASN.1工具源代码,包括编译源码生成工具和各种基本类型构造类型的编解码实现代码
💻 JAVA
字号:
/** * * BEROutputStream : An implementation of the SerializationManager  *                   that can be used to serialize a type to a ByteArrayOutputStream. * * @author Ian Ibbotson ( ibbo@k-int.com ) * @version $Id: BEROutputStream.java,v 1.4 2001/01/18 15:05:47 ianibbo Exp $ * @see    com.k_int.codec.runtime.SerializationManager * * Copyright:   Copyright (C) 2000, Knowledge Integration Ltd. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the license, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite * 330, Boston, MA  02111-1307, USA. * */package com.k_int.codec.runtime;import java.math.BigInteger;import java.util.Vector;import java.util.Stack;import java.util.Enumeration;import java.io.OutputStream;import java.io.ByteArrayOutputStream;import java.io.StringWriter;public class BEROutputStream extends ByteArrayOutputStream implements SerializationManager{  Stack encoding_info = new Stack();  public int tag_class = -1;  public int tag_value = -1;  public boolean is_constructed = false;  private base_codec codec_hint = null;  public BEROutputStream()  {    super();  }  public BEROutputStream(int size)  {    super(size);  }  // Methods from SerializationManager  public int getDirection()  {    return DIRECTION_ENCODE;  }  // Return length of tag encoding  public int tag_codec(boolean is_constructed) throws java.io.IOException  {    // debug("output tag ("+tag_class+","+tag_value+")\n");    if ( tag_class == -1 )      throw new java.io.IOException("Trying to write an un-initialized tag");    int k = tag_class;    if(is_constructed)        k |= 0x20;     if(tag_value < 31) // We can encode in a single octet    {        write(k | tag_value);    }    else // Multiple tag octets    {        // In multiple length tags, first octet gives class & cons, bits 1-5 are all 1        write(k | 0x1f);         // Followed by the integer encoding of the tag, base 128        encodeBase128Int(tag_value);    }    tag_class = -1;    tag_value = -1;    return 1;  }  public String octetstring_codec(Object instance, boolean is_constructed) throws java.io.IOException  {    String retval = (String)instance;    // debug("octetstring_codec "+retval+"\n");    byte[] enc = retval.getBytes();    encodeLength(enc.length);    write(enc);        return (String)instance;  }  public Boolean boolean_codec(Object instance, boolean is_constructed) throws java.io.IOException  {    Boolean retval = (Boolean)instance;    encodeLength(1);    write(retval.booleanValue() ? 1 : 0);    return retval;  }  public BigInteger integer_codec(Object instance, boolean is_constructed) throws java.io.IOException  {    // debug("integer_codec "+(BigInteger)instance);    // Just write out the integer encoding    BigInteger intval = (BigInteger)instance;     if ( intval != null )    {      int i=0;      byte abyte0[] = intval.toByteArray();       if((abyte0[0] & 0x80) != 0)        throw new IllegalArgumentException("Illegal internal encoding");       // byte abyte1[];       // Write the encoding      // if(abyte0[0] != 0)      // {      //   abyte1 = abyte0;      // }      // else      // {      //   i = abyte0.length;      //   abyte1 = new byte[i - 1];      //   System.arraycopy(abyte0, 1, abyte1, 0, i-1);      // }      // encodeLength(abyte1.length);      // write(abyte1);       encodeLength(abyte0.length);      write(abyte0);      flush();    }     return intval;  }  public int[] oid_codec(Object instance, boolean is_constructed) throws java.io.IOException  {    // debug("oid_codec");    int[] oid = (int[])instance;    int len = oid.length;    int len_pos = count;    // Assume OID's will be less than 127 octets in length    write(0);    if ( len > 1 )    {      // We encode by first doing ( 40 * array[0] ) + array[1]      byte first_octet = (byte) ( ( oid[0] * 40 ) + oid[1] );      write(first_octet);       for ( int i=2; i<len; i++ )      {        encodeBase128Int(oid[i]);      }      rewriteLength(len_pos, count-(len_pos+1), 1);    }    return oid;  }  public byte[] any_codec(Object instance, boolean is_constructed) throws java.io.IOException  {    byte[] b = (byte[])instance;    encodeLength(b.length);    write(b);    // write(b,0,b.length);    return b;  }  public AsnBitString bitstring_codec(Object instance, boolean is_constructed) throws java.io.IOException  {    AsnBitString abs = (AsnBitString)instance;    int len = ( abs.getValue().length ) + 1;  // +1 for number of unused bits octet    // debug("bitstring_codec length of contents : "+len);    // Encode the length    encodeLength(len);    write(0);  // Cheat and say that there are no unused octets    write(abs.getValue());    return abs;  }  public AsnNull null_codec(Object instance, boolean is_constructed) throws java.io.IOException  {    AsnNull retval = (AsnNull)instance;    encodeLength(0);       // Length of length encoding for a length of 0 is 0!    // write(0);    return retval;  }   public Object choice(Object current_instance, Object[][] choice_info, int which, String name) throws java.io.IOException  {    // Extract the which element from current_instance    ChoiceType c = (ChoiceType)current_instance;     Integer tagmode = (Integer)(choice_info[c.which][0]);    Integer tagclass = (Integer)(choice_info[c.which][1]);    Integer tagnumber = (Integer)(choice_info[c.which][2]);    // debug("choice_codec ("+name+") tagmode:"+tagmode+"\n");     base_codec codec_to_use = ((base_codec)(choice_info[c.which][3]));     if ( tagmode.equals(SerializationManager.TAGMODE_NONE) )    {      // No tagging, just dive into the decoding      // debug("  <no tagging, so simply calling codec for "+((String)(choice_info[c.which][4]))+">\n");      codec_to_use.serialize(this, c.o, false, ((String)(choice_info[c.which][4])));    }    else    {      if (  tagmode.equals(SerializationManager.IMPLICIT ) )      {        // debug("  <implicit  tagging, so simply calling codec for "+((String)(choice_info[c.which][4]))+">\n");        // Implicit Tagging        implicit_settag(tagclass.intValue(), tagnumber.intValue());        codec_to_use.serialize(this, c.o, false, ((String)(choice_info[c.which][4])));      }      else  // Explicit tagging      {        // debug("  <explicit  tagging, so simply calling codec for "+((String)(choice_info[c.which][4]))+">\n");        constructedBegin(tagclass.intValue(), tagnumber.intValue());        codec_to_use.serialize(this, c.o, false, ((String)(choice_info[c.which][4])));        constructedEnd();      }    }    return current_instance;  }  public boolean sequenceBegin() throws java.io.IOException  {    if ( tag_class < 0 )    {      tag_class = SerializationManager.UNIVERSAL;      tag_value = SerializationManager.SEQUENCE;    }    return constructedBegin(tag_class, tag_value);   }  public boolean sequenceEnd()  {    return constructedEnd();  }  public boolean constructedBegin(int tagclass, int tagnumber)  throws java.io.IOException  {    // debug("Constructed Begin\n");    if ( tag_class < 0 )    {      tag_class = tagclass;      tag_value = tagnumber;    }    tag_codec(true);    CodecStackInfo csi = new CodecStackInfo();    csi.len_offset = count;    csi.lenlen = 4;    // Write dummy length offset (I'm writing 4 octets here.. for no good reason);    write((byte)0);    write((byte)0);    write((byte)0);    write((byte)0);    csi.contents_offset = count;    // debug("Constructed length starts at "+csi.len_offset+" contents start at "+count+"\n");    encoding_info.push(csi);    return true;  }  public boolean constructedEnd()  {    CodecStackInfo csi = (CodecStackInfo)encoding_info.pop();    // debug("Constructed contents end at "+count+"\n");    int length_of_contents = count - csi.contents_offset;    rewriteLength(csi.len_offset, length_of_contents, csi.lenlen);    // debug("Constructed End\n");    return true;  }  public Object implicit_tag(base_codec c, Object current_instance, int tag_class, int tag_number, boolean is_optional, String name) throws java.io.IOException  {    if ( null != current_instance )    {      // debug("implicit_tag "+tag_class+","+tag_number+" "+name+"\n");      implicit_settag(tag_class, tag_number);      c.serialize(this, current_instance, is_optional, name);    }    else    {      // debug("(missing) implicit_tag "+tag_class+","+tag_number+" "+name+"\n");      if ( !is_optional )        throw new java.io.IOException("Missing mandatory member: "+name);    }    return current_instance;  }  public Object explicit_tag(base_codec c, Object current_instance, int tag_class, int tag_number, boolean is_optional, String name) throws java.io.IOException  {    if ( null != current_instance )    {      // debug("explicit_tag "+tag_class+","+tag_number+" "+name+"\n");      constructedBegin(tag_class, tag_number);      c.serialize(this, current_instance, is_optional, name);      constructedEnd();    }    else    {      // debug("(missing) explicit_tag "+tag_class+","+tag_number+" "+name+"\n");      if ( !is_optional )        throw new java.io.IOException("Missing mandatory member: "+name);    }    return current_instance;  }  public boolean sequenceOf(Vector v, base_codec codec) throws java.io.IOException  {    if ( null != v )    {      if ( v.size() > 0 )      {        sequenceBegin();        for ( Enumeration e = v.elements(); e.hasMoreElements(); )         {          Object o = e.nextElement();          codec.serialize(this, o, true, "SequenceOfElement");          // debug("SequenceOf member: "+o+"\n");        }        sequenceEnd();      }    }    return true;  }  public void implicit_settag(int tagclass, int tagvalue)  {    if ( tag_class < 0 )    {      tag_class = tagclass;      tag_value = tagvalue;    }  }  private boolean tag()  {    return true;  }  private int encodeLength(int len)  {    // debug("Encoding length "+len+"\n");    if(len >= 128)    {      byte byte0;       if(len >= 0x1000000)         byte0 = 4;      else if(len >= 0x10000)         byte0 = 3;      else if(len >= 256)         byte0 = 2;      else         byte0 = 1;       write(0x80 | byte0);      for(int j = (byte0 - 1) * 8; j >= 0; j -= 8)        write(len >> j);      return byte0;    }    else    {      // Single length octet      write(len);      return 1;    }  }  private boolean rewriteLength(int pos, int len, int max_octets)  {    // debug("rewriting length..."+len+"\n");    int len_offset = pos;    if ( max_octets > 1 )    {      byte byte0 = (byte)(max_octets-1);  // -1 because max_octets includes length of length encoding      // Encode length of length encoding      buf[len_offset++]=(byte)(0x80 | byte0);      // Length octets      for(int j = (byte0 - 1) * 8; j >= 0; j -= 8)        buf[len_offset++]=(byte)(len >> j);    }    else    {      if ( len > 127 )       {        // Really fatal error        System.err.println("Asked to encode a value > 127 in only one length octet");        System.exit(1);      }      else      {        buf[len_offset] = (byte)len;      }    }    return true;  }  private void debug(String msg)  {    StringWriter sw = new StringWriter();    for ( int i=0; i < encoding_info.size(); i++ )    {      sw.write("    ");    }    sw.write(msg);    System.err.print(sw.toString());  }  private int encodeTag()  {    return 1;  }  private void encodeBase128Int(int value) throws java.io.IOException  {    byte[] enc = new byte[10];    int pos = 0;     while ( ( value > 127 ) && ( pos < 9 ) )    {      enc[pos++] = (byte) ( value & 127 );      value = value >> 7;    }    enc[pos] = (byte)value;     for ( ;pos>=0;pos-- )    {      write( ( enc[pos] | ( pos == 0 ? 0 : 128 ) ) );    }  }   public base_codec getHintCodec()  {    return codec_hint;  }  public void setHintCodec(base_codec c)  {    codec_hint = c;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -