[前][次][番号順一覧][スレッド一覧]

ruby-changes:19636

From: emboss <ko1@a...>
Date: Sun, 22 May 2011 09:01:17 +0900 (JST)
Subject: [ruby-changes:19636] emboss:r31680 (trunk): * ext/openssl/ossl_asn1.c: Default tag lookup in constant time via hash

emboss	2011-05-22 09:01:06 +0900 (Sun, 22 May 2011)

  New Revision: 31680

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=31680

  Log:
    * ext/openssl/ossl_asn1.c: Default tag lookup in constant time via hash
    instead of previous linear algorithm.
    [Ruby 1.9 - Feature #4309][ruby-core:34813]

  Modified files:
    trunk/ChangeLog
    trunk/ext/openssl/ossl_asn1.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 31679)
+++ ChangeLog	(revision 31680)
@@ -1,3 +1,9 @@
+Sun May 22 08:57:13 2011  Martin Bosslet  <Martin.Bosslet@g...>
+
+	* ext/openssl/ossl_asn1.c: Default tag lookup in constant time via hash
+	instead of previous linear algorithm.
+	[Ruby 1.9 - Feature #4309][ruby-core:34813]
+
 Sun May 22 07:54:16 2011  Martin Bosslet  <Martin.Bosslet@g...>
 
 	* ext/openssl/ossl_digest.c: Explain DSS and DSS1 in documentation.
Index: ext/openssl/ossl_asn1.c
===================================================================
--- ext/openssl/ossl_asn1.c	(revision 31679)
+++ ext/openssl/ossl_asn1.c	(revision 31680)
@@ -489,6 +489,8 @@
 
 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);
 
 ASN1_TYPE*
@@ -570,13 +572,13 @@
 static int
 ossl_asn1_default_tag(VALUE obj)
 {
-    int i;
-
-    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;
-	}
+    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);
     }
     ossl_raise(eASN1Error, "universal tag for %s not found",
 	       rb_class2name(CLASS_OF(obj)));
@@ -1765,4 +1767,30 @@
     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_global_variable(&class_tag_map);
 }

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]