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

ruby-changes:14483

From: akr <ko1@a...>
Date: Thu, 14 Jan 2010 04:04:37 +0900 (JST)
Subject: [ruby-changes:14483] Ruby:r26320 (trunk): * time.c (time_mdump): use nano_num and nano_den instead of subnano to

akr	2010-01-14 04:04:17 +0900 (Thu, 14 Jan 2010)

  New Revision: 26320

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

  Log:
    * time.c (time_mdump): use nano_num and nano_den instead of subnano to
      avoid Rational class in marshaled data which prevent unmarshal by
      Ruby 1.8.
      (time_mload): use nano_num and nano_den.

  Modified files:
    trunk/ChangeLog
    trunk/test/ruby/test_time.rb
    trunk/time.c

Index: time.c
===================================================================
--- time.c	(revision 26319)
+++ time.c	(revision 26320)
@@ -103,7 +103,7 @@
 }
 #endif
 
-static ID id_divmod, id_mul, id_submicro, id_subnano;
+static ID id_divmod, id_mul, id_submicro, id_nano_num, id_nano_den;
 static ID id_eq, id_ne, id_quo, id_div, id_cmp, id_lshift;
 
 #define eq(x,y) (RTEST(rb_funcall((x), id_eq, 1, (y))))
@@ -3604,6 +3604,8 @@
     usec = nsec / 1000;
     nsec = nsec % 1000;
 
+    nano = add(LONG2FIX(nsec), subnano);
+
     p = 0x1UL            << 31 | /*  1 */
 	TIME_UTC_P(tobj) << 30 | /*  1 */
 	(year-1900)      << 14 | /* 16 */
@@ -3625,7 +3627,17 @@
 
     str = rb_str_new(buf, 8);
     rb_copy_generic_ivar(str, time);
-    if (nsec) {
+    if (!rb_equal(nano, INT2FIX(0))) {
+        if (TYPE(nano) == T_RATIONAL) {
+            rb_ivar_set(str, id_nano_num, ((struct RRational *)nano)->num);
+            rb_ivar_set(str, id_nano_den, ((struct RRational *)nano)->den);
+        }
+        else {
+            rb_ivar_set(str, id_nano_num, nano);
+            rb_ivar_set(str, id_nano_den, INT2FIX(1));
+        }
+    }
+    if (nsec) { /* submicro is only for Ruby 1.9.1 compatibility */
         /*
          * submicro is formatted in fixed-point packed BCD (without sign).
          * It represent digits under microsecond.
@@ -3644,9 +3656,6 @@
             len = 1;
         rb_ivar_set(str, id_submicro, rb_str_new(buf, len));
     }
-    if (!rb_equal(subnano, INT2FIX(0))) {
-        rb_ivar_set(str, id_subnano, subnano);
-    }
     return str;
 }
 
@@ -3683,18 +3692,22 @@
     struct vtm vtm;
     int i, gmt;
     long nsec;
-    VALUE timexv, submicro, subnano;
+    VALUE timexv, submicro, nano_num, nano_den;
 
     time_modify(time);
 
+    nano_num = rb_attr_get(str, id_nano_num);
+    if (nano_num != Qnil) {
+        st_delete(rb_generic_ivar_table(str), (st_data_t*)&id_nano_num, 0);
+    }
+    nano_den = rb_attr_get(str, id_nano_den);
+    if (nano_den != Qnil) {
+        st_delete(rb_generic_ivar_table(str), (st_data_t*)&id_nano_den, 0);
+    }
     submicro = rb_attr_get(str, id_submicro);
     if (submicro != Qnil) {
         st_delete(rb_generic_ivar_table(str), (st_data_t*)&id_submicro, 0);
     }
-    subnano = rb_attr_get(str, id_subnano);
-    if (subnano != Qnil) {
-        st_delete(rb_generic_ivar_table(str), (st_data_t*)&id_subnano, 0);
-    }
     rb_copy_generic_ivar(time, str);
 
     StringValue(str);
@@ -3736,7 +3749,13 @@
 	usec = (long)(s & 0xfffff);
         nsec = usec * 1000;
 
-        if (submicro != Qnil) {
+
+        vtm.subsecx = mulquo(LONG2FIX(nsec), INT2FIX(TIME_SCALE), LONG2FIX(1000000000));
+        if (nano_num != Qnil) {
+            VALUE nano = quo(num_exact(nano_num), num_exact(nano_den));
+            vtm.subsecx = add(vtm.subsecx, mulquo(nano, INT2FIX(TIME_SCALE), LONG2FIX(1000000000)));
+        }
+        else if (submicro != Qnil) { /* for Ruby 1.9.1 compatibility */
             unsigned char *ptr;
             long len;
             int digit;
@@ -3754,12 +3773,6 @@
             }
 end_submicro: ;
         }
-
-        vtm.subsecx = mulquo(LONG2FIX(nsec), INT2FIX(TIME_SCALE), LONG2FIX(1000000000));
-        if (subnano != Qnil) {
-            subnano = num_exact(subnano);
-            vtm.subsecx = add(vtm.subsecx, mulquo(subnano, INT2FIX(TIME_SCALE), LONG2FIX(1000000000)));
-        }
         timexv = timegmxv(&vtm);
     }
 
@@ -3819,7 +3832,8 @@
     id_divmod = rb_intern("divmod");
     id_mul = rb_intern("*");
     id_submicro = rb_intern("submicro");
-    id_subnano = rb_intern("subnano");
+    id_nano_num = rb_intern("nano_num");
+    id_nano_den = rb_intern("nano_den");
 
     rb_cTime = rb_define_class("Time", rb_cObject);
     rb_include_module(rb_cTime, rb_mComparable);
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 26319)
+++ ChangeLog	(revision 26320)
@@ -1,3 +1,10 @@
+Thu Jan 14 04:01:50 2010  Tanaka Akira  <akr@f...>
+
+	* time.c (time_mdump): use nano_num and nano_den instead of subnano to
+	  avoid Rational class in marshaled data which prevent unmarshal by
+	  Ruby 1.8.
+	  (time_mload): use nano_num and nano_den.
+
 Wed Jan 13 11:57:38 2010  Marc-Andre Lafortune  <ruby-core@m...>
 
 	* object.c (rb_class_initialize): Make sure BasicObject doesn't get
Index: test/ruby/test_time.rb
===================================================================
--- test/ruby/test_time.rb	(revision 26319)
+++ test/ruby/test_time.rb	(revision 26320)
@@ -191,6 +191,11 @@
     assert_marshal_roundtrip(Time.at(0, 0.120))
   end
 
+  def test_marshal_rational
+    assert_marshal_roundtrip(Time.at(0, Rational(1,3)))
+    assert_not_match(/Rational/, Marshal.dump(Time.at(0, Rational(1,3))))
+  end
+
   def test_marshal_ivar
     t = Time.at(123456789, 987654.321)
     t.instance_eval { @var = 135 }

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

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