Hi.
This patch creates a _dump-method for Time that matches what Ruby 1.8
creates. The code is created by looking at time.c in the Ruby distro.
I have also added some methods to support marshal_dump later on. What's
missing is a correct implementation of _load in Time, but that will come
soon too.
Regards
Ola Bini
Index: src/org/jruby/RubyTime.java
===================================================================
RCS file: /cvsroot/jruby/jruby/src/org/jruby/RubyTime.java,v
retrieving revision 1.18
diff -u -r1.18 RubyTime.java
--- src/org/jruby/RubyTime.java 26 Mar 2006 21:21:40 -0000 1.18
+++ src/org/jruby/RubyTime.java 31 Mar 2006 12:45:46 -0000
@@ -269,4 +269,38 @@
// modified to match how hash is calculated in 1.8.2
return getRuntime().newFixnum((int)(((cal.getTimeInMillis() / 1000) ^
microseconds()) << 1) >> 1);
}
+
+ public RubyString dump(final IRubyObject[] args) {
+ if (args.length > 1) {
+ throw getRuntime().newArgumentError(0, 1);
+ }
+ final RubyFixnum limit = (args.length ==
0)?RubyFixnum.minus_one(getRuntime()):(RubyFixnum)args[0];
+ return (RubyString)mdump(new IRubyObject[] {this});
+ }
+
+ public RubyObject mdump(final IRubyObject[] args) {
+ final RubyTime obj = (RubyTime)args[0];
+ final Calendar cel = obj.gmtime().cal;
+ final byte buf[] = new byte[8];
+ int pe =
+ 0x1 << 31 |
+ (cel.get(Calendar.YEAR)-1900) << 14 |
+ cel.get(Calendar.MONTH) << 10 |
+ cel.get(Calendar.DAY_OF_MONTH) << 5 |
+ cel.get(Calendar.HOUR_OF_DAY);
+
+ int se =
+ cel.get(Calendar.MINUTE) << 26 |
+ cel.get(Calendar.SECOND) << 20 |
+ cel.get(Calendar.MILLISECOND);
+ for(int i=0;i<4;i++) {
+ buf[i] = (byte)(pe & 0xFF);
+ pe >>= 8;
+ }
+ for(int i=4;i<8;i++) {
+ buf[i] = (byte)(se & 0xFF);
+ se >>= 8;
+ }
+ return RubyString.newString(obj.getRuntime(),buf);
+ }
}
Index: src/org/jruby/runtime/marshal/MarshalStream.java
===================================================================
RCS file:
/cvsroot/jruby/jruby/src/org/jruby/runtime/marshal/MarshalStream.java,v
retrieving revision 1.13
diff -u -r1.13 MarshalStream.java
--- src/org/jruby/runtime/marshal/MarshalStream.java 26 Oct 2005 05:34:13
-0000 1.13
+++ src/org/jruby/runtime/marshal/MarshalStream.java 31 Mar 2006 10:21:42
-0000
@@ -54,6 +54,10 @@
private int depth = 0;
private MarshalCache cache;
+ private final static char TYPE_USRMARSHAL = 'U';
+ private final static char TYPE_USERDEF = 'u';
+
+
public MarshalStream(IRuby runtime, OutputStream out, int depthLimit)
throws IOException {
super(out);
@@ -72,6 +76,8 @@
}
if (! shouldBeRegistered(value)) {
writeDirectly(value);
+ } else if (hasNewUserDefinedMarshaling(value)) {
+ userNewMarshal(value);
} else if (hasUserDefinedMarshaling(value)) {
userMarshal(value);
} else {
@@ -115,14 +121,22 @@
return value.respondsTo("_dump");
}
+ private boolean hasNewUserDefinedMarshaling(IRubyObject value) {
+ return value.respondsTo("marshal_dump");
+ }
+
private void userMarshal(IRubyObject value) throws IOException {
- out.write('u');
+ out.write(TYPE_USERDEF);
dumpObject(RubySymbol.newSymbol(runtime,
value.getMetaClass().getName()));
RubyString marshaled = (RubyString) value.callMethod("_dump",
runtime.newFixnum(depthLimit));
dumpString(marshaled.getValue());
}
+ private void userNewMarshal(IRubyObject value) throws IOException {
+ out.write(TYPE_USRMARSHAL);
+ }
+
public void dumpString(String value) throws IOException {
dumpInt(value.length());
out.write(RubyString.stringToBytes(value));
Index: src/org/jruby/runtime/builtin/meta/TimeMetaClass.java
===================================================================
RCS file:
/cvsroot/jruby/jruby/src/org/jruby/runtime/builtin/meta/TimeMetaClass.java,v
retrieving revision 1.2
diff -u -r1.2 TimeMetaClass.java
--- src/org/jruby/runtime/builtin/meta/TimeMetaClass.java 26 Mar 2006
21:21:40 -0000 1.2
+++ src/org/jruby/runtime/builtin/meta/TimeMetaClass.java 31 Mar 2006
11:04:13 -0000
@@ -76,6 +76,7 @@
defineSingletonMethod("mktime", Arity.optional(), "new_local");
defineSingletonMethod("utc", Arity.optional(), "new_utc");
defineSingletonMethod("gm", Arity.optional(), "new_utc");
+ defineSingletonMethod("_load", Arity.optional(), "s_load");
// Missing getgm, getlocal, getutc (alias of getgm), gmt_offset,
gmtoff (alias of
// gmt_offset), utc_offset (alias of gmt_offset)
@@ -115,6 +116,7 @@
defineMethod("localtime", Arity.noArguments());
defineMethod("hash", Arity.noArguments());
defineMethod("initialize_copy", Arity.singleArgument());
+ defineMethod("_dump", Arity.optional(),"dump");
}
};
@@ -169,6 +171,10 @@
public RubyTime new_utc(IRubyObject[] args) {
return createTime(args, true);
}
+
+ public RubyTime s_load(IRubyObject[] args) {
+ return null;
+ }
private static final String[] months = {"jan", "feb", "mar", "apr", "may",
"jun",
"jul", "aug", "sep", "oct", "nov",
"dec"};