This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

FYI: TimeZone/VMTimeZone split integrated from GNU Classpath


Hi,

This patch implements the TimeZone/VMTimeZone split we talked about a
while ago. It was already in GNU Classpath for a while (and was in the
0.11 developer snapshot release). It also adds two small (but important)
bugfixes.

2004-09-25  Mark Wielaard  <mark@klomp.org>

        * Makefile.am (core_java_source_files): Add VMTimeZone.java.
        (nat_source_files): Rename natTimeZone.cc to natVMTimeZone.cc.
        * Makefile.in: Regenerated.

        * gcj/javaprims.h: Regenerated.

        * java/util/TimeZone.java (defaultZone): Use VMTimeZone.
        (getDefaultTimeZone): Make package private. Check that GMToffset
        contains at least one digit.
        (getDefaultTimeZoneId, readTimeZoneFile, readtzFile): (Re)Moved to
        VMTimeZone.
        * util/VMTimeZone.java: New file with above methods.

        * java/util/natTimeZone.cc: Removed (renamed).
        * java/util/natVMTimeZone.cc: Added (renamed).

2004-09-25  Jeroen Frijters  <jeroen@frijters.net>

        * java/util/TimeZone.java
        (getDefaultTimeZone): Fixed test to distinguish between hours and
        minutes in specified timezone.

The native code is now almost identical between GNU Classpath and
libgcj. It might be a good idea to extract most code out
natVMTimeZone.cc (VMTimeZone.c in classpath) and put it in its own file
so it can be easier shared between the projects. But I haven't done this
yet.

Committed to mainline.

Cheers,

Mark
Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.415
diff -u -r1.415 Makefile.am
--- Makefile.am	25 Sep 2004 19:04:27 -0000	1.415
+++ Makefile.am	25 Sep 2004 21:55:35 -0000
@@ -2424,6 +2424,7 @@
 java/util/TreeSet.java \
 java/util/TooManyListenersException.java \
 java/util/Vector.java \
+java/util/VMTimeZone.java	\
 java/util/WeakHashMap.java \
 java/util/logging/ConsoleHandler.java \
 java/util/logging/ErrorManager.java \
@@ -3191,7 +3192,7 @@
 java/nio/natDirectByteBufferImpl.cc \
 java/text/natCollator.cc \
 java/util/natResourceBundle.cc \
-java/util/natTimeZone.cc \
+java/util/natVMTimeZone.cc \
 java/util/zip/natDeflater.cc \
 java/util/zip/natInflater.cc
 
Index: gcj/javaprims.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gcj/javaprims.h,v
retrieving revision 1.52
diff -u -r1.52 javaprims.h
--- gcj/javaprims.h	12 Aug 2004 16:20:09 -0000	1.52
+++ gcj/javaprims.h	25 Sep 2004 21:55:37 -0000
@@ -151,6 +151,7 @@
       class Comparable;
       class Compiler;
       class ConcreteProcess;
+      class ConcreteProcess$EOFInputStream;
       class ConcreteProcess$ProcessManager;
       class Double;
       class Error;
@@ -359,6 +360,7 @@
       class TreeMap$SubMap;
       class TreeMap$TreeIterator;
       class TreeSet;
+      class VMTimeZone;
       class Vector;
       class WeakHashMap;
       class WeakHashMap$WeakBucket;
Index: java/util/TimeZone.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/util/TimeZone.java,v
retrieving revision 1.19
diff -u -r1.19 TimeZone.java
--- java/util/TimeZone.java	26 Aug 2004 16:10:53 -0000	1.19
+++ java/util/TimeZone.java	25 Sep 2004 21:55:37 -0000
@@ -38,9 +38,7 @@
 
 
 package java.util;
-import gnu.classpath.Configuration;
 
-import java.io.*;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.text.DateFormatSymbols;
@@ -90,14 +88,9 @@
   /**
    * Tries to get the default TimeZone for this system if not already
    * set.  It will call <code>getDefaultTimeZone(String)</code> with
-   * the result of
-   * <code>System.getProperty("user.timezone")</code>,
-   * <code>System.getenv("TZ")</code>,
-   * <code>readTimeZoneFile("/etc/timezone")</code>,
-   * <code>readtzFile("/etc/localtime")</code> and
-   * <code>getDefaultTimeZoneId()</code>
-   * till a supported TimeZone is found.
-   * If every method fails GMT is returned.
+   * the result of <code>System.getProperty("user.timezone")</code>.
+   * If that fails it calls <code>VMTimeZone.getDefaultTimeZoneId()</code>.
+   * If that also fails GMT is returned.
    */
   private static synchronized TimeZone defaultZone()
   {
@@ -109,11 +102,6 @@
 	    {
 	      public Object run()
 	      {
-		if (Configuration.INIT_LOAD_LIBRARY)
-		  {
-		    System.loadLibrary("javautil");
-		  }
-		
 		TimeZone zone = null;
 		
 		// Prefer System property user.timezone.
@@ -121,37 +109,9 @@
 		if (tzid != null && !tzid.equals(""))
 		  zone = getDefaultTimeZone(tzid);
 		
-		// See if TZ environment variable is set and accessible.
-		if (zone == null)
-		  {
-		    tzid = System.getenv("TZ");
-		    if (tzid != null && !tzid.equals(""))
-		      zone = getDefaultTimeZone(tzid);
-		  }
-		
-		// Try to parse /etc/timezone.
+		// Try platfom specific way.
 		if (zone == null)
-		  {
-		    tzid = readTimeZoneFile("/etc/timezone");
-		    if (tzid != null && !tzid.equals(""))
-		      zone = getDefaultTimeZone(tzid);
-		  }
-		
-		// Try to parse /etc/localtime
-		if (zone == null)
-		  {
-		    tzid = readtzFile("/etc/localtime");
-		    if (tzid != null && !tzid.equals(""))
-		      zone = getDefaultTimeZone(tzid);
-		  }
-		
-		// Try some system specific way
-		if (zone == null)
-		  {
-		    tzid = getDefaultTimeZoneId();
-		    if (tzid != null && !tzid.equals(""))
-		      zone = getDefaultTimeZone(tzid);
-		  }
+		  zone = VMTimeZone.getDefaultTimeZoneId();
 		
 		// Fall back on GMT.
 		if (zone == null)
@@ -843,238 +803,6 @@
   }
 
   /**
-   * This method returns a time zone id string which is in the form
-   * (standard zone name) or (standard zone name)(GMT offset) or
-   * (standard zone name)(GMT offset)(daylight time zone name).  The
-   * GMT offset can be in seconds, or where it is evenly divisible by
-   * 3600, then it can be in hours.  The offset must be the time to
-   * add to the local time to get GMT.  If a offset is given and the
-   * time zone observes daylight saving then the (daylight time zone
-   * name) must also be given (otherwise it is assumed the time zone
-   * does not observe any daylight savings).
-   * <p>
-   * The result of this method is given to getDefaultTimeZone(String)
-   * which tries to map the time zone id to a known TimeZone.  See
-   * that method on how the returned String is mapped to a real
-   * TimeZone object.
-   */
-  private static native String getDefaultTimeZoneId();
-
-  /**
-   * Tries to read the time zone name from a file. Only the first
-   * consecutive letters, digits, slashes, dashes and underscores are
-   * read from the file. If the file cannot be read or an IOException
-   * occurs null is returned.
-   * <p>
-   * The /etc/timezone file is not standard, but a lot of systems have
-   * it. If it exist the first line always contains a string
-   * describing the timezone of the host of domain. Some systems
-   * contain a /etc/TIMEZONE file which is used to set the TZ
-   * environment variable (which is checked before /etc/timezone is
-   * read).
-   */
-  private static String readTimeZoneFile(String file)
-  {
-    File f = new File(file);
-    if (!f.exists())
-      return null;
-
-    InputStreamReader isr = null;
-    try
-      {
-	FileInputStream fis = new FileInputStream(f);
-	BufferedInputStream bis = new BufferedInputStream(fis);
-	isr = new InputStreamReader(bis);
-	
-	StringBuffer sb = new StringBuffer();
-	int i = isr.read();
-	while (i != -1)
-	  {
-	    char c = (char) i;
-	    if (Character.isLetter(c) || Character.isDigit(c)
-		|| c == '/' || c == '-' || c == '_')
-	      {
-		sb.append(c);
-		i = isr.read();
-	      }
-	    else
-	      break;
-	  }
-	return sb.toString();
-      }
-    catch (IOException ioe)
-      {
-	// Parse error, not a proper tzfile.
-	return null;
-      }
-    finally
-      {
-	try
-	  {
-	    if (isr != null)
-	      isr.close();
-	  }
-	catch (IOException ioe)
-	  {
-	    // Error while close, nothing we can do.
-	  }
-      }
-  }
-
-  /**
-   * Tries to read a file as a "standard" tzfile and return a time
-   * zone id string as expected by <code>getDefaultTimeZone(String)</code>.
-   * If the file doesn't exist, an IOException occurs or it isn't a tzfile
-   * that can be parsed null is returned.
-   * <p>
-   * The tzfile structure (as also used by glibc) is described in the Olson
-   * tz database archive as can be found at
-   * <code>ftp://elsie.nci.nih.gov/pub/</code>.
-   * <p>
-   * At least the following platforms support the tzdata file format
-   * and /etc/localtime (GNU/Linux, Darwin, Solaris and FreeBSD at
-   * least). Some systems (like Darwin) don't start the file with the
-   * required magic bytes 'TZif', this implementation can handle
-   * that).
-   */
-  private static String readtzFile(String file)
-  {
-    File f = new File(file);
-    if (!f.exists())
-      return null;
-    
-    DataInputStream dis = null;
-    try
-      {
-        FileInputStream fis = new FileInputStream(f);
-        BufferedInputStream bis = new BufferedInputStream(fis);
-        dis = new DataInputStream(bis);
-	
-        // Make sure we are reading a tzfile.
-        byte[] tzif = new byte[4];
-        dis.readFully(tzif);
-        if (tzif[0] == 'T' && tzif[1] == 'Z'
-            && tzif[2] == 'i' && tzif[3] == 'f')
-	  // Reserved bytes, ttisgmtcnt, ttisstdcnt and leapcnt
-	  skipFully(dis, 16 + 3 * 4);
-	else
-	  // Darwin has tzdata files that don't start with the TZif marker
-	  skipFully(dis, 16 + 3 * 4 - 4);
-	
-	int timecnt = dis.readInt();
-	int typecnt = dis.readInt();
-	if (typecnt > 0)
-	  {
-	    int charcnt = dis.readInt();
-	    // Transition times plus indexed transition times.
-	    skipFully(dis, timecnt * (4 + 1));
-	    
-	    // Get last gmt_offset and dst/non-dst time zone names.
-	    int abbrind = -1;
-	    int dst_abbrind = -1;
-	    int gmt_offset = 0;
-	    while (typecnt-- > 0)
-	      {
-		// gmtoff
-		int offset = dis.readInt();
-		int dst = dis.readByte();
-		if (dst == 0)
-		  {
-		    abbrind = dis.readByte();
-		    gmt_offset = offset;
-		  }
-		else
-		  dst_abbrind = dis.readByte();
-	      }
-	    
-	    // gmt_offset is the offset you must add to UTC/GMT to
-	    // get the local time, we need the offset to add to
-	    // the local time to get UTC/GMT.
-	    gmt_offset *= -1;
-	    
-	    // Turn into hours if possible.
-	    if (gmt_offset % 3600 == 0)
-	      gmt_offset /= 3600;
-	    
-	    if (abbrind >= 0)
-	      {
-		byte[] names = new byte[charcnt];
-		dis.readFully(names);
-		int j = abbrind;
-		while (j < charcnt && names[j] != 0)
-		  j++;
-		
-		String zonename = new String(names, abbrind, j - abbrind,
-					     "ASCII");
-		
-		String dst_zonename;
-		if (dst_abbrind >= 0)
-		  {
-		    j = dst_abbrind;
-		    while (j < charcnt && names[j] != 0)
-		      j++;
-		    dst_zonename = new String(names, dst_abbrind,
-					      j - dst_abbrind, "ASCII");
-		  }
-		else
-		  dst_zonename = "";
-		
-		// Only use gmt offset when necessary.
-		// Also special case GMT+/- timezones.
-		String offset_string;
-		if ("".equals(dst_zonename)
-		    && (gmt_offset == 0
-			|| zonename.startsWith("GMT+")
-			|| zonename.startsWith("GMT-")))
-		  offset_string = "";
-		else
-		  offset_string = Integer.toString(gmt_offset);
-		
-		String id = zonename + offset_string + dst_zonename;
-		
-		return id;
-	      }
-	  }
-	
-	// Something didn't match while reading the file.
-	return null;
-      }
-    catch (IOException ioe)
-      {
-	// Parse error, not a proper tzfile.
-	return null;
-      }
-    finally
-      {
-	try
-	  {
-	    if (dis != null)
-	      dis.close();
-	  }
-	catch(IOException ioe)
-	  {
-	    // Error while close, nothing we can do.
-	  }
-      }
-  }
-  
-  /**
-   * Skips the requested number of bytes in the given InputStream.
-   * Throws EOFException if not enough bytes could be skipped.
-   * Negative numbers of bytes to skip are ignored.
-   */
-  private static void skipFully(InputStream is, long l) throws IOException
-  {
-    while (l > 0)
-      {
-        long k = is.skip(l);
-        if (k <= 0)
-          throw new EOFException();
-        l -= k;
-      }
-  }
-  
-  /**
    * Maps a time zone name (with optional GMT offset and daylight time
    * zone name) to one of the known time zones.  This method called
    * with the result of <code>System.getProperty("user.timezone")</code>
@@ -1111,7 +839,7 @@
    * The standard time zone name for The Netherlands is "Europe/Amsterdam",
    * but can also be given as "CET-1CEST".
    */
-  private static TimeZone getDefaultTimeZone(String sysTimeZoneId)
+  static TimeZone getDefaultTimeZone(String sysTimeZoneId)
   {
     // First find start of GMT offset info and any Daylight zone name.
     int startGMToffset = 0;
@@ -1119,7 +847,11 @@
     for (int i = 0; i < sysTimeZoneIdLength && startGMToffset == 0; i++)
       {
 	char c = sysTimeZoneId.charAt(i);
-	if (c == '+' || c == '-' || Character.isDigit(c))
+	if (Character.isDigit(c))
+	  startGMToffset = i;
+	else if ((c == '+' || c == '-')
+		 && i + 1 < sysTimeZoneIdLength
+		 && Character.isDigit(sysTimeZoneId.charAt(i + 1)))
 	  startGMToffset = i;
       }
     
@@ -1152,7 +884,7 @@
 	// Offset could be in hours or seconds.  Convert to millis.
 	// The offset is given as the time to add to local time to get GMT
 	// we need the time to add to GMT to get localtime.
-	if (gmtOffset < 24)
+	if (Math.abs(gmtOffset) < 24)
 	  gmtOffset *= 60 * 60;
 	gmtOffset *= -1000;
       }
Index: java/util/VMTimeZone.java
===================================================================
RCS file: java/util/VMTimeZone.java
diff -N java/util/VMTimeZone.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/util/VMTimeZone.java	25 Sep 2004 21:55:37 -0000
@@ -0,0 +1,345 @@
+/* java.util.VMTimeZone
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
+   Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+import gnu.classpath.Configuration;
+
+import java.io.*;
+
+/**
+ *
+ */
+final class VMTimeZone
+{
+  static
+  {
+    if (Configuration.INIT_LOAD_LIBRARY)
+      {
+	System.loadLibrary("javautil");
+      }
+  }
+		
+  /**
+   * This method returns a time zone id string which is in the form
+   * (standard zone name) or (standard zone name)(GMT offset) or
+   * (standard zone name)(GMT offset)(daylight time zone name).  The
+   * GMT offset can be in seconds, or where it is evenly divisible by
+   * 3600, then it can be in hours.  The offset must be the time to
+   * add to the local time to get GMT.  If a offset is given and the
+   * time zone observes daylight saving then the (daylight time zone
+   * name) must also be given (otherwise it is assumed the time zone
+   * does not observe any daylight savings).
+   * <p>
+   * The result of this method is given to the method
+   * TimeZone.getDefaultTimeZone(String) which tries to map the time
+   * zone id to a known TimeZone.  See that method on how the returned
+   * String is mapped to a real TimeZone object.
+   * <p>
+   * The reference implementation which is made for GNU/Posix like
+   * systems calls <code>System.getenv("TZ")</code>,
+   * <code>readTimeZoneFile("/etc/timezone")</code>,
+   * <code>readtzFile("/etc/localtime")</code> and finally
+   * <code>getSystemTimeZoneId()</code> till a supported TimeZone is
+   * found through <code>TimeZone.getDefaultTimeZone(String)</code>.
+   * If every method fails <code>null</code> is returned (which means
+   * the TimeZone code will fall back on GMT as default time zone).
+   * <p>
+   * Note that this method is called inside a
+   * <code>AccessController.doPrivileged()</code> block and runs with
+   * the priviliges of the java.util system classes.  It will only be
+   * called when the default time zone is not yet set, the system
+   * property user.timezone isn't set and it is requested for the
+   * first time.
+   */
+  static TimeZone getDefaultTimeZoneId()
+  {
+    TimeZone zone = null;
+
+    // See if TZ environment variable is set and accessible.
+    String tzid = System.getenv("TZ");
+    if (tzid != null && !tzid.equals(""))
+      zone = TimeZone.getDefaultTimeZone(tzid);
+
+    // Try to parse /etc/timezone.
+    if (zone == null)
+      {
+	tzid = readTimeZoneFile("/etc/timezone");
+	if (tzid != null && !tzid.equals(""))
+	  zone = TimeZone.getDefaultTimeZone(tzid);
+      }
+    
+    // Try to parse /etc/localtime
+    if (zone == null)
+      {
+	tzid = readtzFile("/etc/localtime");
+	if (tzid != null && !tzid.equals(""))
+	  zone = TimeZone.getDefaultTimeZone(tzid);
+      }
+
+    // Try some system specific way
+    if (zone == null)
+      {
+	tzid = getSystemTimeZoneId();
+	if (tzid != null && !tzid.equals(""))
+	  zone = TimeZone.getDefaultTimeZone(tzid);
+      }
+
+    return zone;
+  }
+
+  /**
+   * Tries to read the time zone name from a file. Only the first
+   * consecutive letters, digits, slashes, dashes and underscores are
+   * read from the file. If the file cannot be read or an IOException
+   * occurs null is returned.
+   * <p>
+   * The /etc/timezone file is not standard, but a lot of systems have
+   * it. If it exist the first line always contains a string
+   * describing the timezone of the host of domain. Some systems
+   * contain a /etc/TIMEZONE file which is used to set the TZ
+   * environment variable (which is checked before /etc/timezone is
+   * read).
+   */
+  private static String readTimeZoneFile(String file)
+  {
+    File f = new File(file);
+    if (!f.exists())
+      return null;
+
+    InputStreamReader isr = null;
+    try
+      {
+	FileInputStream fis = new FileInputStream(f);
+	BufferedInputStream bis = new BufferedInputStream(fis);
+	isr = new InputStreamReader(bis);
+	
+	StringBuffer sb = new StringBuffer();
+	int i = isr.read();
+	while (i != -1)
+	  {
+	    char c = (char) i;
+	    if (Character.isLetter(c) || Character.isDigit(c)
+		|| c == '/' || c == '-' || c == '_')
+	      {
+		sb.append(c);
+		i = isr.read();
+	      }
+	    else
+	      break;
+	  }
+	return sb.toString();
+      }
+    catch (IOException ioe)
+      {
+	// Parse error, not a proper tzfile.
+	return null;
+      }
+    finally
+      {
+	try
+	  {
+	    if (isr != null)
+	      isr.close();
+	  }
+	catch (IOException ioe)
+	  {
+	    // Error while close, nothing we can do.
+	  }
+      }
+  }
+
+  /**
+   * Tries to read a file as a "standard" tzfile and return a time
+   * zone id string as expected by <code>getDefaultTimeZone(String)</code>.
+   * If the file doesn't exist, an IOException occurs or it isn't a tzfile
+   * that can be parsed null is returned.
+   * <p>
+   * The tzfile structure (as also used by glibc) is described in the Olson
+   * tz database archive as can be found at
+   * <code>ftp://elsie.nci.nih.gov/pub/</code>.
+   * <p>
+   * At least the following platforms support the tzdata file format
+   * and /etc/localtime (GNU/Linux, Darwin, Solaris and FreeBSD at
+   * least). Some systems (like Darwin) don't start the file with the
+   * required magic bytes 'TZif', this implementation can handle
+   * that).
+   */
+  private static String readtzFile(String file)
+  {
+    File f = new File(file);
+    if (!f.exists())
+      return null;
+    
+    DataInputStream dis = null;
+    try
+      {
+        FileInputStream fis = new FileInputStream(f);
+        BufferedInputStream bis = new BufferedInputStream(fis);
+        dis = new DataInputStream(bis);
+	
+        // Make sure we are reading a tzfile.
+        byte[] tzif = new byte[4];
+        dis.readFully(tzif);
+        if (tzif[0] == 'T' && tzif[1] == 'Z'
+            && tzif[2] == 'i' && tzif[3] == 'f')
+	  // Reserved bytes, ttisgmtcnt, ttisstdcnt and leapcnt
+	  skipFully(dis, 16 + 3 * 4);
+	else
+	  // Darwin has tzdata files that don't start with the TZif marker
+	  skipFully(dis, 16 + 3 * 4 - 4);
+	
+	int timecnt = dis.readInt();
+	int typecnt = dis.readInt();
+	if (typecnt > 0)
+	  {
+	    int charcnt = dis.readInt();
+	    // Transition times plus indexed transition times.
+	    skipFully(dis, timecnt * (4 + 1));
+	    
+	    // Get last gmt_offset and dst/non-dst time zone names.
+	    int abbrind = -1;
+	    int dst_abbrind = -1;
+	    int gmt_offset = 0;
+	    while (typecnt-- > 0)
+	      {
+		// gmtoff
+		int offset = dis.readInt();
+		int dst = dis.readByte();
+		if (dst == 0)
+		  {
+		    abbrind = dis.readByte();
+		    gmt_offset = offset;
+		  }
+		else
+		  dst_abbrind = dis.readByte();
+	      }
+	    
+	    // gmt_offset is the offset you must add to UTC/GMT to
+	    // get the local time, we need the offset to add to
+	    // the local time to get UTC/GMT.
+	    gmt_offset *= -1;
+	    
+	    // Turn into hours if possible.
+	    if (gmt_offset % 3600 == 0)
+	      gmt_offset /= 3600;
+	    
+	    if (abbrind >= 0)
+	      {
+		byte[] names = new byte[charcnt];
+		dis.readFully(names);
+		int j = abbrind;
+		while (j < charcnt && names[j] != 0)
+		  j++;
+		
+		String zonename = new String(names, abbrind, j - abbrind,
+					     "ASCII");
+		
+		String dst_zonename;
+		if (dst_abbrind >= 0)
+		  {
+		    j = dst_abbrind;
+		    while (j < charcnt && names[j] != 0)
+		      j++;
+		    dst_zonename = new String(names, dst_abbrind,
+					      j - dst_abbrind, "ASCII");
+		  }
+		else
+		  dst_zonename = "";
+		
+		// Only use gmt offset when necessary.
+		// Also special case GMT+/- timezones.
+		String offset_string;
+		if ("".equals(dst_zonename)
+		    && (gmt_offset == 0
+			|| zonename.startsWith("GMT+")
+			|| zonename.startsWith("GMT-")))
+		  offset_string = "";
+		else
+		  offset_string = Integer.toString(gmt_offset);
+		
+		String id = zonename + offset_string + dst_zonename;
+		
+		return id;
+	      }
+	  }
+	
+	// Something didn't match while reading the file.
+	return null;
+      }
+    catch (IOException ioe)
+      {
+	// Parse error, not a proper tzfile.
+	return null;
+      }
+    finally
+      {
+	try
+	  {
+	    if (dis != null)
+	      dis.close();
+	  }
+	catch(IOException ioe)
+	  {
+	    // Error while close, nothing we can do.
+	  }
+      }
+  }
+  
+  /**
+   * Skips the requested number of bytes in the given InputStream.
+   * Throws EOFException if not enough bytes could be skipped.
+   * Negative numbers of bytes to skip are ignored.
+   */
+  private static void skipFully(InputStream is, long l) throws IOException
+  {
+    while (l > 0)
+      {
+        long k = is.skip(l);
+        if (k <= 0)
+          throw new EOFException();
+        l -= k;
+      }
+  }
+
+  /**
+   * Tries to get the system time zone id through native code.
+   */
+  private static native String getSystemTimeZoneId();
+}
Index: java/util/natTimeZone.cc
===================================================================
RCS file: java/util/natTimeZone.cc
diff -N java/util/natTimeZone.cc
--- java/util/natTimeZone.cc	26 Aug 2004 16:10:54 -0000	1.7
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,145 +0,0 @@
-// natTimeZone.cc -- Native side of TimeZone class.
-
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
-   Free Software Foundation
-
-   This file is part of libgcj.
-
-This software is copyrighted work licensed under the terms of the
-Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
-details.  */
-
-#include <config.h>
-#include <platform.h>
-
-#include <gcj/cni.h>
-#include <jvm.h>
-
-#include <java/util/TimeZone.h>
-#include <java/lang/Character.h>
-#include <java/lang/Integer.h>
-
-#include <stdio.h>
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  include <time.h>
-# endif
-#endif
-
-#include <string.h>
-
-/**
- * This method returns a time zone id string which is in the form
- * (standard zone name) or (standard zone name)(GMT offset) or
- * (standard zone name)(GMT offset)(daylight time zone name).  The
- * GMT offset can be in seconds, or where it is evenly divisible by
- * 3600, then it can be in hours.  The offset must be the time to
- * add to the local time to get GMT.  If a offset is given and the
- * time zone observes daylight saving then the (daylight time zone
- * name) must also be given (otherwise it is assumed the time zone
- * does not observe any daylight savings).
- * <p>
- * The result of this method is given to getDefaultTimeZone(String)
- * which tries to map the time zone id to a known TimeZone.  See
- * that method on how the returned String is mapped to a real
- * TimeZone object.
- */
-jstring
-java::util::TimeZone::getDefaultTimeZoneId ()
-{
-  struct tm tim;
-#ifndef HAVE_LOCALTIME_R
-  struct tm *lt_tim;
-#endif
-#ifdef HAVE_TM_ZONE
-  int month;
-#endif
-  time_t current_time;
-  long tzoffset;
-  const char *tz1, *tz2;
-  char *tzid;
-
-  time(&current_time);
-#ifdef HAVE_LOCALTIME_R
-  localtime_r(&current_time, &tim);
-#else
-  /* Fall back on non-thread safe localtime. */
-  lt_tim = localtime(&current_time);
-  memcpy(&tim, lt_tim, sizeof (struct tm));
-#endif
-  mktime(&tim);
-
-#ifdef HAVE_TM_ZONE
-  /* We will cycle through the months to make sure we hit dst. */
-  month = tim.tm_mon;
-  tz1 = tz2 = NULL;
-  while (tz1 == NULL || tz2 == NULL)
-    {
-      if (tim.tm_isdst > 0)
-        tz2 = tim.tm_zone;
-      else if (tz1 == NULL)
-        {
-          tz1 = tim.tm_zone;
-          month = tim.tm_mon;
-        }
-
-      if (tz1 == NULL || tz2 == NULL)
-        {
-          tim.tm_mon++;
-          tim.tm_mon %= 12;
-        }
-
-      if (tim.tm_mon == month && tz2 == NULL)
-        tz2 = "";
-      else
-        mktime(&tim);
-    }
-  /* We want to make sure the tm struct we use later on is not dst. */
-  tim.tm_mon = month;
-  mktime(&tim);
-#elif defined (HAVE_TZNAME)
-  /* If dst is never used, tzname[1] is the empty string. */
-  tzset();
-  tz1 = tzname[0];
-  tz2 = tzname[1];
-#else
-  /* Some targets have no concept of timezones. Assume GMT without dst. */
-  tz1 = "GMT";
-  tz2 = "";
-#endif
-
-#ifdef STRUCT_TM_HAS_GMTOFF
-  /* tm_gmtoff is the number of seconds that you must add to GMT to get
-     local time, we need the number of seconds to add to the local time
-     to get GMT. */
-  tzoffset = -1L * tim.tm_gmtoff;
-#elif HAVE_UNDERSCORE_TIMEZONE
-  tzoffset = _timezone;
-#elif HAVE_TIMEZONE
-  /* timezone is secs WEST of UTC. */
-  tzoffset = timezone;	
-#else
-  /* FIXME: there must be another global if neither tm_gmtoff nor timezone
-     is available, esp. if tzname is valid.
-     Richard Earnshaw <rearnsha@arm.com> has suggested using difftime to
-     calculate between gmtime and localtime (and accounting for possible
-     daylight savings time) as an alternative. */
-  tzoffset = 0L;
-#endif
-
-  if ((tzoffset % 3600) == 0)
-    tzoffset = tzoffset / 3600;
-
-  tzid = (char*) _Jv_Malloc (strlen(tz1) + strlen(tz2) + 6);
-  sprintf(tzid, "%s%ld%s", tz1, tzoffset, tz2);
-  jstring retval = JvNewStringUTF (tzid);
-  _Jv_Free (tzid);
-
-  return retval;
-}
Index: java/util/natVMTimeZone.cc
===================================================================
RCS file: java/util/natVMTimeZone.cc
diff -N java/util/natVMTimeZone.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/util/natVMTimeZone.cc	25 Sep 2004 21:55:37 -0000
@@ -0,0 +1,145 @@
+// natVMTimeZone.cc -- Native side of VMTimeZone class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
+   Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/util/VMTimeZone.h>
+#include <java/lang/Character.h>
+#include <java/lang/Integer.h>
+
+#include <stdio.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+#include <string.h>
+
+/**
+ * This method returns a time zone id string which is in the form
+ * (standard zone name) or (standard zone name)(GMT offset) or
+ * (standard zone name)(GMT offset)(daylight time zone name).  The
+ * GMT offset can be in seconds, or where it is evenly divisible by
+ * 3600, then it can be in hours.  The offset must be the time to
+ * add to the local time to get GMT.  If a offset is given and the
+ * time zone observes daylight saving then the (daylight time zone
+ * name) must also be given (otherwise it is assumed the time zone
+ * does not observe any daylight savings).
+ * <p>
+ * The result of this method is given to getDefaultTimeZone(String)
+ * which tries to map the time zone id to a known TimeZone.  See
+ * that method on how the returned String is mapped to a real
+ * TimeZone object.
+ */
+jstring
+java::util::VMTimeZone::getSystemTimeZoneId()
+{
+  struct tm tim;
+#ifndef HAVE_LOCALTIME_R
+  struct tm *lt_tim;
+#endif
+#ifdef HAVE_TM_ZONE
+  int month;
+#endif
+  time_t current_time;
+  long tzoffset;
+  const char *tz1, *tz2;
+  char *tzid;
+
+  time(&current_time);
+#ifdef HAVE_LOCALTIME_R
+  localtime_r(&current_time, &tim);
+#else
+  /* Fall back on non-thread safe localtime. */
+  lt_tim = localtime(&current_time);
+  memcpy(&tim, lt_tim, sizeof (struct tm));
+#endif
+  mktime(&tim);
+
+#ifdef HAVE_TM_ZONE
+  /* We will cycle through the months to make sure we hit dst. */
+  month = tim.tm_mon;
+  tz1 = tz2 = NULL;
+  while (tz1 == NULL || tz2 == NULL)
+    {
+      if (tim.tm_isdst > 0)
+        tz2 = tim.tm_zone;
+      else if (tz1 == NULL)
+        {
+          tz1 = tim.tm_zone;
+          month = tim.tm_mon;
+        }
+
+      if (tz1 == NULL || tz2 == NULL)
+        {
+          tim.tm_mon++;
+          tim.tm_mon %= 12;
+        }
+
+      if (tim.tm_mon == month && tz2 == NULL)
+        tz2 = "";
+      else
+        mktime(&tim);
+    }
+  /* We want to make sure the tm struct we use later on is not dst. */
+  tim.tm_mon = month;
+  mktime(&tim);
+#elif defined (HAVE_TZNAME)
+  /* If dst is never used, tzname[1] is the empty string. */
+  tzset();
+  tz1 = tzname[0];
+  tz2 = tzname[1];
+#else
+  /* Some targets have no concept of timezones. Assume GMT without dst. */
+  tz1 = "GMT";
+  tz2 = "";
+#endif
+
+#ifdef STRUCT_TM_HAS_GMTOFF
+  /* tm_gmtoff is the number of seconds that you must add to GMT to get
+     local time, we need the number of seconds to add to the local time
+     to get GMT. */
+  tzoffset = -1L * tim.tm_gmtoff;
+#elif HAVE_UNDERSCORE_TIMEZONE
+  tzoffset = _timezone;
+#elif HAVE_TIMEZONE
+  /* timezone is secs WEST of UTC. */
+  tzoffset = timezone;	
+#else
+  /* FIXME: there must be another global if neither tm_gmtoff nor timezone
+     is available, esp. if tzname is valid.
+     Richard Earnshaw <rearnsha@arm.com> has suggested using difftime to
+     calculate between gmtime and localtime (and accounting for possible
+     daylight savings time) as an alternative. */
+  tzoffset = 0L;
+#endif
+
+  if ((tzoffset % 3600) == 0)
+    tzoffset = tzoffset / 3600;
+
+  tzid = (char*) _Jv_Malloc (strlen(tz1) + strlen(tz2) + 6);
+  sprintf(tzid, "%s%ld%s", tz1, tzoffset, tz2);
+  jstring retval = JvNewStringUTF (tzid);
+  _Jv_Free (tzid);
+
+  return retval;
+}

Attachment: signature.asc
Description: This is a digitally signed message part


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]