make nestedvm work under SableVM
[nestedvm.git] / src / org / ibex / nestedvm / util / Platform.java
1 package org.ibex.nestedvm.util;
2
3 import java.io.*;
4 import java.net.*;
5 import java.util.*;
6
7 import java.text.DateFormatSymbols;
8
9 public abstract class Platform {
10     Platform() { }
11     private static final Platform p;
12     
13     static {
14         float version;
15         try {
16             if(getProperty("java.vm.name").equals("SableVM"))
17                 version = 1.2f;
18             else
19                 version = Float.valueOf(getProperty("java.specification.version")).floatValue();
20         } catch(Exception e) {
21             System.err.println("WARNING: " + e + " while trying to find jvm version -  assuming 1.1");
22             version = 1.1f;
23         }
24         String platformClass;
25         if(version >= 1.4f) platformClass = "Jdk14";
26         else if(version >= 1.3f) platformClass = "Jdk13";
27         else if(version >= 1.2f) platformClass = "Jdk12";
28         else if(version >= 1.1f) platformClass = "Jdk11";
29         else throw new Error("JVM Specification version: " + version + " is too old. (see org.ibex.util.Platform to add support)");
30         
31         try {
32             p = (Platform) Class.forName(Platform.class.getName() + "$" + platformClass).newInstance();
33         } catch(Exception e) {
34             e.printStackTrace();
35             throw new Error("Error instansiating platform class");
36         }
37     }
38     
39     public static String getProperty(String key) {
40         try {
41             return System.getProperty(key);
42         } catch(SecurityException e) {
43             return null;
44         }
45     }
46     
47     
48     abstract boolean _atomicCreateFile(File f) throws IOException;
49     public static boolean atomicCreateFile(File f) throws IOException { return p._atomicCreateFile(f); }
50     
51     abstract void _socketHalfClose(Socket s, boolean output) throws IOException;
52     public static void socketHalfClose(Socket s, boolean output) throws IOException { p._socketHalfClose(s,output); }
53     
54     abstract void _socketSetKeepAlive(Socket s, boolean on) throws SocketException;
55     public static void socketSetKeepAlive(Socket s, boolean on) throws SocketException { p._socketSetKeepAlive(s,on); }
56     
57     abstract InetAddress _inetAddressFromBytes(byte[] a) throws UnknownHostException;
58     public static InetAddress inetAddressFromBytes(byte[] a) throws UnknownHostException { return p._inetAddressFromBytes(a); }
59     
60     abstract String _timeZoneGetDisplayName(TimeZone tz, boolean dst, boolean showlong, Locale l);
61     public static String timeZoneGetDisplayName(TimeZone tz, boolean dst, boolean showlong, Locale l) { return p._timeZoneGetDisplayName(tz,dst,showlong,l); }
62     public static String timeZoneGetDisplayName(TimeZone tz, boolean dst, boolean showlong) { return timeZoneGetDisplayName(tz,dst,showlong,Locale.getDefault()); }
63     
64     abstract RandomAccessFile _truncatedRandomAccessFile(File f, String mode) throws IOException;
65     public static RandomAccessFile truncatedRandomAccessFile(File f, String mode) throws IOException { return p._truncatedRandomAccessFile(f,mode); }
66     
67     // FEATURE: Make sure GCClass can get rid of uncalled superclass methdos
68     
69     static class Jdk11 extends Platform {
70         boolean _atomicCreateFile(File f) throws IOException {
71             // This is not atomic, but its the best we can do on jdk 1.1
72             if(f.exists()) return false;
73             new FileOutputStream(f).close();
74             return true;
75         }
76         void _socketHalfClose(Socket s, boolean output) throws IOException {
77             throw new IOException("half closing sockets not supported");
78         }
79         InetAddress _inetAddressFromBytes(byte[] a) throws UnknownHostException {
80             if(a.length != 4) throw new UnknownHostException("only ipv4 addrs supported");
81             return InetAddress.getByName(""+(a[0]&0xff)+"."+(a[1]&0xff)+"."+(a[2]&0xff)+"."+(a[3]&0xff));
82         }
83         void _socketSetKeepAlive(Socket s, boolean on) throws SocketException {
84             if(on) throw new SocketException("keepalive not supported");
85         }
86         String _timeZoneGetDisplayName(TimeZone tz, boolean dst, boolean showlong, Locale l) {
87             String[][] zs  = new DateFormatSymbols(l).getZoneStrings();
88             String id = tz.getID();
89             for(int i=0;i<zs.length;i++)
90                 if(zs[i][0].equals(id))
91                     return zs[i][dst ? (showlong ? 3 : 4) : (showlong ? 1 : 2)];
92             StringBuffer sb = new StringBuffer("GMT");
93             int off = tz.getRawOffset() / 1000;
94             if(off < 0) { sb.append("-"); off = -off; }
95             else sb.append("+");
96             sb.append(off/3600); off = off%3600;
97             if(off > 0) sb.append(":").append(off/60); off=off%60;
98             if(off > 0) sb.append(":").append(off);
99             return sb.toString();
100         }
101         
102         RandomAccessFile _truncatedRandomAccessFile(File f, String mode) throws IOException {
103             new FileOutputStream(f).close();
104             return new RandomAccessFile(f,mode);
105         }
106     }
107     
108     static class Jdk12 extends Jdk11 {
109         boolean _atomicCreateFile(File f) throws IOException {
110             return f.createNewFile();
111         }
112         
113         String _timeZoneGetDisplayName(TimeZone tz, boolean dst, boolean showlong, Locale l) {
114             return tz.getDisplayName(dst,showlong ? TimeZone.LONG : TimeZone.SHORT, l);
115         }
116         
117         RandomAccessFile _truncatedRandomAccessFile(File f, String mode) throws IOException {
118             RandomAccessFile raf = new RandomAccessFile(f,mode);
119             raf.setLength(0);
120             return raf;
121         }       
122     }
123     
124     static class Jdk13 extends Jdk12 {
125         void _socketHalfClose(Socket s, boolean output) throws IOException {
126             if(output) s.shutdownOutput();
127             else s.shutdownInput();
128         }
129         
130         void _socketSetKeepAlive(Socket s, boolean on) throws SocketException {
131             s.setKeepAlive(on);
132         }
133     }
134     
135     static class Jdk14 extends Jdk13 {
136         InetAddress _inetAddressFromBytes(byte[] a) throws UnknownHostException { return InetAddress.getByAddress(a); } 
137     }
138 }