
Property changes on: ruby/ext/openssl
___________________________________________________________________
Modified: svn:ignore
   - GNUmakefile
Makefile
dep
extconf.h
mkmf.log
openssl.a
conftest.dSYM

   + GNUmakefile
Makefile
dep
extconf.h
mkmf.log
openssl.a
conftest.dSYM
openssl.so


Index: ruby/ext/openssl/ossl_asn1.c
===================================================================
--- ruby/ext/openssl/ossl_asn1.c	(revision 30640)
+++ ruby/ext/openssl/ossl_asn1.c	(working copy)
@@ -454,7 +454,7 @@
 } ossl_asn1_info_t;
 
 static ossl_asn1_info_t ossl_asn1_info[] = {
-    { "EOC",               &cASN1EndOfContent,    },  /*  0 */
+    { "END_OF_CONTENT",    &cASN1EndOfContent,    },  /*  0 */
     { "BOOLEAN",           &cASN1Boolean,         },  /*  1 */
     { "INTEGER",           &cASN1Integer,         },  /*  2 */
     { "BIT_STRING",        &cASN1BitString,       },  /*  3 */
@@ -487,10 +487,34 @@
     { "BMPSTRING",         &cASN1BMPString,       },  /* 30 */
 };
 
+
+
 int ossl_asn1_info_size = (sizeof(ossl_asn1_info)/sizeof(ossl_asn1_info[0]));
 
+static VALUE class_tag_map;
+
 static int ossl_asn1_default_tag(VALUE obj);
 
+static VALUE
+ossl_asn1_default_tag_class(VALUE self, VALUE klass)
+{
+    VALUE tag = rb_hash_lookup(class_tag_map, klass);
+    if (tag != Qnil) {
+        return tag;
+    }
+
+    ossl_raise(eASN1Error, "universal tag for %s not found",
+	       rb_class2name(klass));
+
+    return Qnil; /* dummy */
+}
+
+static VALUE
+ossl_asn1_default_tag_public(VALUE self, VALUE obj)
+{
+  return INT2NUM(ossl_asn1_default_tag(obj));
+}
+
 ASN1_TYPE*
 ossl_asn1_get_asn1type(VALUE obj)
 {
@@ -570,14 +594,15 @@
 static int
 ossl_asn1_default_tag(VALUE obj)
 {
-    int i;
+    VALUE tmp_class = CLASS_OF(obj);
+    while (tmp_class) {
+        VALUE tag = rb_hash_lookup(class_tag_map, tmp_class);
+        if (tag != Qnil) {
+            return NUM2INT(tag);
+        }
+        tmp_class = RCLASS_SUPER(tmp_class);
+    }
 
-    for(i = 0; i < ossl_asn1_info_size; i++){
-	if(ossl_asn1_info[i].klass &&
-	   rb_obj_is_kind_of(obj, *ossl_asn1_info[i].klass)){
-	    return i;
-	}
-    }
     ossl_raise(eASN1Error, "universal tag for %s not found",
 	       rb_class2name(CLASS_OF(obj)));
 
@@ -841,7 +866,7 @@
             ossl_asn1_set_infinite_length(asn1data, Qtrue);
         else
             ossl_asn1_set_infinite_length(asn1data, Qfalse);
-        
+
 	rb_ary_push(ary, asn1data);
 	length -= len;
         if(once) break;
@@ -1190,6 +1215,8 @@
     rb_define_module_function(mASN1, "traverse", ossl_asn1_traverse, 1);
     rb_define_module_function(mASN1, "decode", ossl_asn1_decode, 1);
     rb_define_module_function(mASN1, "decode_all", ossl_asn1_decode_all, 1);
+    rb_define_module_function(mASN1, "default_tag_of_class", ossl_asn1_default_tag_class, 1);
+    rb_define_module_function(mASN1, "default_tag", ossl_asn1_default_tag_public, 1);
     ary = rb_ary_new();
     rb_define_const(mASN1, "UNIVERSAL_TAG_NAME", ary);
     for(i = 0; i < ossl_asn1_info_size; i++){
@@ -1260,4 +1287,31 @@
     rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);
 
     rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0);
+
+    class_tag_map = rb_hash_new();
+    rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(0));
+    rb_hash_aset(class_tag_map, cASN1Boolean, INT2NUM(1));
+    rb_hash_aset(class_tag_map, cASN1Integer, INT2NUM(2));
+    rb_hash_aset(class_tag_map, cASN1BitString, INT2NUM(3));
+    rb_hash_aset(class_tag_map, cASN1OctetString, INT2NUM(4));
+    rb_hash_aset(class_tag_map, cASN1Null, INT2NUM(5));
+    rb_hash_aset(class_tag_map, cASN1ObjectId, INT2NUM(6));
+    rb_hash_aset(class_tag_map, cASN1Enumerated, INT2NUM(10));
+    rb_hash_aset(class_tag_map, cASN1UTF8String, INT2NUM(12));
+    rb_hash_aset(class_tag_map, cASN1Sequence, INT2NUM(16));
+    rb_hash_aset(class_tag_map, cASN1Set, INT2NUM(17));
+    rb_hash_aset(class_tag_map, cASN1NumericString, INT2NUM(18));
+    rb_hash_aset(class_tag_map, cASN1PrintableString, INT2NUM(19));
+    rb_hash_aset(class_tag_map, cASN1T61String, INT2NUM(20));
+    rb_hash_aset(class_tag_map, cASN1VideotexString, INT2NUM(21));
+    rb_hash_aset(class_tag_map, cASN1IA5String, INT2NUM(22));
+    rb_hash_aset(class_tag_map, cASN1UTCTime, INT2NUM(23));
+    rb_hash_aset(class_tag_map, cASN1GeneralizedTime, INT2NUM(24));
+    rb_hash_aset(class_tag_map, cASN1GraphicString, INT2NUM(25));
+    rb_hash_aset(class_tag_map, cASN1ISO64String, INT2NUM(26));
+    rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(27));
+    rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(28));
+    rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(30));
+
+    rb_define_const(mASN1, "CLASS_TAG_MAP", class_tag_map);
 }
Index: ruby/test/openssl/test_asn1.rb
===================================================================
--- ruby/test/openssl/test_asn1.rb	(revision 30640)
+++ ruby/test/openssl/test_asn1.rb	(working copy)
@@ -430,4 +430,54 @@
     end
   end
   
+  def test_default_tag_of_class
+    OpenSSL::ASN1::CLASS_TAG_MAP.each do |klass, tag|
+      assert_equal(tag, OpenSSL::ASN1.default_tag_of_class(klass))
+    end
+  end
+  
+  def test_default_tag
+    assert_equal(0, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::EndOfContent.new))    
+    assert_equal(1, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::Boolean.new(true)))
+    assert_equal(2, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::Integer.new(1)))
+    assert_equal(3, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::BitString.new("\x01")))
+    assert_equal(4, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::OctetString.new("\x01")))    
+    assert_equal(5, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::Null.new(nil)))    
+    assert_equal(6, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::ObjectId.new("1.2.3.4.5")))    
+    assert_equal(10, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::Enumerated.new(1)))    
+    assert_equal(12, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::UTF8String.new("a"))) 
+    assert_equal(16, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::Sequence.new([])))    
+    assert_equal(17, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::Set.new([])))    
+    assert_equal(18, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::NumericString.new("a")))
+    assert_equal(19, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::PrintableString.new("a")))
+    assert_equal(20, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::T61String.new("a")))
+    assert_equal(21, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::VideotexString.new("a")))
+    assert_equal(22, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::IA5String.new("a")))
+    assert_equal(23, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::UTCTime.new(Time.now)))
+    assert_equal(24, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::GeneralizedTime.new(Time.now)))
+    assert_equal(25, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::GraphicString.new("a")))
+    assert_equal(26, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::ISO64String.new("a")))
+    assert_equal(27, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::GeneralString.new("a")))
+    assert_equal(28, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::UniversalString.new("a")))
+    assert_equal(30, OpenSSL::ASN1.default_tag(OpenSSL::ASN1::BMPString.new("a")))
+  end
+  
+  def test_default_tag_sub_class
+    asn1_class = Class.new(OpenSSL::ASN1::Integer)
+    asn1 = asn1_class.new(8)
+    assert_equal(2, OpenSSL::ASN1.default_tag(asn1))
+  end
+  
+  def test_default_tag_of_class_negative
+    assert_raises(OpenSSL::ASN1::ASN1Error) do
+      OpenSSL::ASN1.default_tag_of_class(Array)
+    end
+  end
+    
+  def test_default_tag_negative
+    assert_raises(OpenSSL::ASN1::ASN1Error) do
+      OpenSSL::ASN1.default_tag(OpenSSL::ASN1::ASN1Data.new(1, 2, nil))
+    end
+  end
+  
 end if defined?(OpenSSL)
