This commit is contained in:
jfrijters 2003-03-17 14:02:46 +00:00
Родитель b4b73ec1c4
Коммит 66d7c812b3
20 изменённых файлов: 1680 добавлений и 3073 удалений

Просмотреть файл

@ -627,10 +627,13 @@ class ClassFile
{ {
return classLoader.LoadClassBySlashedName(name); return classLoader.LoadClassBySlashedName(name);
} }
catch(Exception) catch(Exception x)
{ {
// TODO consider what to do with this error, may be a command line switch?
// TODO it might not be a good idea to catch .NET system exceptions here // TODO it might not be a good idea to catch .NET system exceptions here
if(JVM.LogClassLoadFailures)
{
Console.Error.WriteLine(x);
}
return new UnloadableTypeWrapper(name); return new UnloadableTypeWrapper(name);
} }
} }

Просмотреть файл

@ -127,7 +127,7 @@ class ClassLoaderWrapper
internal void LoadRemappedTypes() internal void LoadRemappedTypes()
{ {
nativeMethods = new Hashtable(); nativeMethods = new Hashtable();
// NOTE interfaces have *not* java/lang/Object as the base type (even though they do in the class file) // NOTE interfaces do *not* have java/lang/Object as the base type (even though they do in the class file)
types["java.lang.Cloneable"] = new RemappedTypeWrapper(this, ModifiersAttribute.GetModifiers(typeof(java.lang.Cloneable)), "java/lang/Cloneable", typeof(java.lang.Cloneable), new TypeWrapper[0], null); types["java.lang.Cloneable"] = new RemappedTypeWrapper(this, ModifiersAttribute.GetModifiers(typeof(java.lang.Cloneable)), "java/lang/Cloneable", typeof(java.lang.Cloneable), new TypeWrapper[0], null);
typeToTypeWrapper.Add(typeof(java.lang.Cloneable), types["java.lang.Cloneable"]); typeToTypeWrapper.Add(typeof(java.lang.Cloneable), types["java.lang.Cloneable"]);
types["java.io.Serializable"] = new RemappedTypeWrapper(this, ModifiersAttribute.GetModifiers(typeof(java.io.Serializable)), "java/io/Serializable", typeof(java.io.Serializable), new TypeWrapper[0], null); types["java.io.Serializable"] = new RemappedTypeWrapper(this, ModifiersAttribute.GetModifiers(typeof(java.io.Serializable)), "java/io/Serializable", typeof(java.io.Serializable), new TypeWrapper[0], null);
@ -152,6 +152,11 @@ class ClassLoaderWrapper
types.Add(name, tw); types.Add(name, tw);
typeToTypeWrapper.Add(tw.Type, tw); typeToTypeWrapper.Add(tw.Type, tw);
} }
}
internal void LoadRemappedTypesStep2()
{
MapXml.Root map = MapXmlGenerator.Generate();
foreach(MapXml.Class c in map.remappings) foreach(MapXml.Class c in map.remappings)
{ {
((RemappedTypeWrapper)types[c.Name]).LoadRemappings(c); ((RemappedTypeWrapper)types[c.Name]).LoadRemappings(c);
@ -175,8 +180,18 @@ class ClassLoaderWrapper
return LoadClassByDottedName(name.Replace('/', '.')); return LoadClassByDottedName(name.Replace('/', '.'));
} }
// TODO implement vmspec 5.3.4 Loading Constraints
internal TypeWrapper LoadClassByDottedName(string name) internal TypeWrapper LoadClassByDottedName(string name)
{
TypeWrapper type = LoadClassByDottedNameFast(name);
if(type != null)
{
return type;
}
throw JavaException.ClassNotFoundException(name);
}
// TODO implement vmspec 5.3.4 Loading Constraints
internal TypeWrapper LoadClassByDottedNameFast(string name)
{ {
if(name == null) if(name == null)
{ {
@ -222,8 +237,7 @@ class ClassLoaderWrapper
case 'Z': case 'Z':
return GetBootstrapClassLoader().CreateArrayType(name, typeof(bool), dims); return GetBootstrapClassLoader().CreateArrayType(name, typeof(bool), dims);
default: default:
// TODO I'm not sure this is the right exception here (instead we could throw a NoClassDefFoundError) return null;
throw JavaException.ClassNotFoundException(name);
} }
} }
if(this == GetBootstrapClassLoader()) if(this == GetBootstrapClassLoader())
@ -247,7 +261,7 @@ class ClassLoaderWrapper
} }
if(javaClassLoader == null) if(javaClassLoader == null)
{ {
throw JavaException.ClassNotFoundException(name); return null;
} }
} }
// NOTE just like Java does (I think), we take the classloader lock before calling the loadClass method // NOTE just like Java does (I think), we take the classloader lock before calling the loadClass method
@ -755,6 +769,7 @@ class ClassLoaderWrapper
{ {
bootstrapClassLoader = new ClassLoaderWrapper(null); bootstrapClassLoader = new ClassLoaderWrapper(null);
bootstrapClassLoader.LoadRemappedTypes(); bootstrapClassLoader.LoadRemappedTypes();
bootstrapClassLoader.LoadRemappedTypesStep2();
} }
return bootstrapClassLoader; return bootstrapClassLoader;
} }

Просмотреть файл

@ -68,6 +68,8 @@ sealed class JavaException
private class BootstrapClassMissing : Exception {} private class BootstrapClassMissing : Exception {}
private static ConstructorInfo classNotFoundConstructor;
internal static Exception ClassNotFoundException(string s, params object[] args) internal static Exception ClassNotFoundException(string s, params object[] args)
{ {
// HACK if java.lang.ClassNotFoundException is not found, this method would recurse until the // HACK if java.lang.ClassNotFoundException is not found, this method would recurse until the
@ -86,8 +88,11 @@ sealed class JavaException
classNotFound = true; classNotFound = true;
//Console.WriteLine("ClassNotFoundException: " + s); //Console.WriteLine("ClassNotFoundException: " + s);
s = String.Format(s, args); s = String.Format(s, args);
ConstructorInfo ci = ClassLoaderWrapper.GetType("java.lang.ClassNotFoundException").GetConstructor(new Type[] { typeof(string) }); if(classNotFoundConstructor == null)
return (Exception)ci.Invoke(new object[] { s }); {
classNotFoundConstructor = ClassLoaderWrapper.GetType("java.lang.ClassNotFoundException").GetConstructor(new Type[] { typeof(string) });
}
return (Exception)classNotFoundConstructor.Invoke(new object[] { s });
} }
catch(BootstrapClassMissing) catch(BootstrapClassMissing)
{ {

Просмотреть файл

@ -27,100 +27,6 @@ using System.Reflection;
public class StringHelper public class StringHelper
{ {
public static string NewString(char[] data, int offset, int count, bool dont_copy)
{
return new String(data, offset, count);
}
public static string NewString(sbyte[] sdata)
{
return NewString(sdata, 0, sdata.Length);
}
public static string NewString(sbyte[] sdata, int hibyte)
{
return NewString(sdata, hibyte, 0, sdata.Length);
}
public static string NewString(sbyte[] sdata, int offset, int count)
{
// TODO what encoding should this use?
// TODO could use the unsafe constructor that takes sbyte*, but I don't know if that is worthwhile to be unsafe for
byte[] data = new byte[sdata.Length];
for(int i = 0; i < data.Length; i++)
{
data[i] = (byte)sdata[i];
}
try {
return System.Text.Encoding.ASCII.GetString(data, offset, count);
}
catch {
return null;
}
}
public static string NewString(sbyte[] sdata, int hibyte, int offset, int count)
{
// TODO benchmark this versus using a stringbuilder instead of a char[]
hibyte <<= 8;
char[] data = new char[count];
for(int i = 0; i < count; i++)
{
// TODO what happens for negative bytes?
data[i] = (char)(((byte)sdata[i + offset]) | hibyte);
}
return new String(data);
}
public static string NewString(sbyte[] sdata, string charsetName)
{
return NewString(sdata, 0, sdata.Length, charsetName);
}
public static string NewString(sbyte[] sdata, int offset, int count, string charsetName)
{
// HACK special case for UTF8, I really need to implement this by
// redirecting to the classpath character encoding support
if(charsetName == "UTF8")
{
char[] ch = new Char[count];
int l = 0;
for(int i = 0; i < count; i++)
{
int c = (byte)sdata[offset + i];
int char2, char3;
switch (c >> 4)
{
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// 0xxxxxxx
break;
case 12: case 13:
// 110x xxxx 10xx xxxx
char2 = (byte)sdata[offset + ++i];
c = (((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
// 1110 xxxx 10xx xxxx 10xx xxxx
char2 = (byte)sdata[offset + ++i];
char3 = (byte)sdata[offset + ++i];
c = (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
break;
}
ch[l++] = (char)c;
}
return new String(ch, 0, l);
}
// TODO don't use reflection, but write a Java helper class and redirect this method there
Type t = ClassLoaderWrapper.GetType("gnu.java.io.EncodingManager");
try {
object decoder = t.InvokeMember("getDecoder", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new object[] { charsetName });
return new String((char[])decoder.GetType().InvokeMember("convertToChars", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, decoder, new object[] { sdata, offset, count }));
}
catch (TargetInvocationException ex) {
throw ExceptionHelper.MapExceptionFast(ex.InnerException);
}
}
public static string valueOf(bool b) public static string valueOf(bool b)
{ {
return b ? "true" : "false"; return b ? "true" : "false";
@ -216,91 +122,12 @@ public class StringHelper
return 0; return 0;
} }
public static bool equalsIgnoreCase(string s1, string s2)
{
return String.Compare(s1, s2, true) == 0;
}
public static int compareToIgnoreCase(string s1, string s2)
{
return String.Compare(s1, s2, true);
}
public static int compareTo(string s1, string s2)
{
int len = Math.Min(s1.Length, s2.Length);
for(int i = 0; i < len; i++)
{
int diff = s1[i] - s2[i];
if(diff != 0)
{
return diff;
}
}
return s1.Length - s2.Length;
}
public static sbyte[] getBytes(string s)
{
byte[] data = System.Text.Encoding.ASCII.GetBytes(s);
sbyte[] sdata = new sbyte[data.Length];
for(int i = 0; i < data.Length; i++)
{
sdata[i] = (sbyte)data[i];
}
return sdata;
}
public static sbyte[] getBytes(string s, string charsetName)
{
// TODO don't use reflection, but write a Java helper class and redirect this method there
char[] ch = s.ToCharArray();
Type t = ClassLoaderWrapper.GetType("gnu.java.io.EncodingManager");
object encoder = t.InvokeMember("getEncoder", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new object[] { charsetName });
return (sbyte[])encoder.GetType().InvokeMember("convertToBytes", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, encoder, new object[] { ch, 0, ch.Length });
}
public static void getBytes(string s, int srcBegin, int srcEnd, sbyte[] dst, int dstBegin)
{
if(srcBegin > srcEnd)
{
throw JavaException.ArrayIndexOutOfBoundsException();
}
for(int i = 0; i < (srcEnd - srcBegin); i++)
{
dst[i + dstBegin] = (sbyte)s[i + srcBegin];
}
}
public static object subSequence(string s, int offset, int count) public static object subSequence(string s, int offset, int count)
{ {
// TODO // TODO
throw new NotImplementedException(); throw new NotImplementedException();
} }
public static bool regionMatches(string s, int toffset, string other, int ooffset, int len)
{
return regionMatches(s, false, toffset, other, ooffset, len);
}
public static bool regionMatches(string s, bool ignoreCase, int toffset, string other, int ooffset, int len)
{
if(toffset < 0 || ooffset < 0 || toffset + len > s.Length || ooffset + len > other.Length)
{
return false;
}
while(--len >= 0)
{
char c1 = s[toffset++];
char c2 = other[ooffset++];
if(c1 != c2 && (!ignoreCase || (Char.ToLower(c1) != Char.ToLower(c2) && (Char.ToUpper(c1) != Char.ToUpper(c2)))))
{
return false;
}
}
return true;
}
// NOTE argument is of type object, because otherwise the code that calls this function // NOTE argument is of type object, because otherwise the code that calls this function
// has to be much more complex // has to be much more complex
public static int hashCode(object s) public static int hashCode(object s)
@ -313,18 +140,6 @@ public class StringHelper
return h; return h;
} }
public static string toUpperCase(string s, object locale)
{
// TODO
return s.ToUpper();
}
public static string toLowerCase(string s, object locale)
{
// TODO
return s.ToLower();
}
public static int indexOf(string s, char ch, int fromIndex) public static int indexOf(string s, char ch, int fromIndex)
{ {
// Java allow fromIndex to both below zero or above the length of the string, .NET doesn't // Java allow fromIndex to both below zero or above the length of the string, .NET doesn't
@ -379,6 +194,17 @@ public class StringHelper
} }
return String.Concat(s1, s2); return String.Concat(s1, s2);
} }
private static object CASE_INSENSITIVE_ORDER;
public static object GetCaseInsensitiveOrder()
{
if(CASE_INSENSITIVE_ORDER == null)
{
CASE_INSENSITIVE_ORDER = Activator.CreateInstance(ClassLoaderWrapper.GetType("java.lang.String$CaseInsensitiveComparator"), true);
}
return CASE_INSENSITIVE_ORDER;
}
} }
public class StringBufferHelper public class StringBufferHelper

Просмотреть файл

@ -829,27 +829,27 @@ class UnloadableTypeWrapper : TypeWrapper
protected override FieldWrapper GetFieldImpl(string fieldName) protected override FieldWrapper GetFieldImpl(string fieldName)
{ {
throw new InvalidOperationException("GetFieldImpl called on UnloadableTypeWrapper"); throw new InvalidOperationException("GetFieldImpl called on UnloadableTypeWrapper: " + Name);
} }
protected override MethodWrapper GetMethodImpl(MethodDescriptor md) protected override MethodWrapper GetMethodImpl(MethodDescriptor md)
{ {
throw new InvalidOperationException("GetMethodImpl called on UnloadableTypeWrapper"); throw new InvalidOperationException("GetMethodImpl called on UnloadableTypeWrapper: " + Name);
} }
public override Type Type public override Type Type
{ {
get get
{ {
throw new InvalidOperationException("get_Type called on UnloadableTypeWrapper"); throw new InvalidOperationException("get_Type called on UnloadableTypeWrapper: " + Name);
} }
} }
public override bool IsInterface public override bool IsInterface
{ {
get get
{ {
throw new InvalidOperationException("get_IsInterface called on UnloadableTypeWrapper"); throw new InvalidOperationException("get_IsInterface called on UnloadableTypeWrapper: " + Name);
} }
} }
@ -857,7 +857,7 @@ class UnloadableTypeWrapper : TypeWrapper
{ {
get get
{ {
throw new InvalidOperationException("get_Interfaces called on UnloadableTypeWrapper"); throw new InvalidOperationException("get_Interfaces called on UnloadableTypeWrapper: " + Name);
} }
} }
@ -865,7 +865,7 @@ class UnloadableTypeWrapper : TypeWrapper
{ {
get get
{ {
throw new InvalidOperationException("get_InnerClasses called on UnloadableTypeWrapper"); throw new InvalidOperationException("get_InnerClasses called on UnloadableTypeWrapper: " + Name);
} }
} }
@ -873,13 +873,13 @@ class UnloadableTypeWrapper : TypeWrapper
{ {
get get
{ {
throw new InvalidOperationException("get_DeclaringTypeWrapper called on UnloadableTypeWrapper"); throw new InvalidOperationException("get_DeclaringTypeWrapper called on UnloadableTypeWrapper: " + Name);
} }
} }
public override void Finish() public override void Finish()
{ {
throw new InvalidOperationException("Finish called on UnloadableTypeWrapper"); throw new InvalidOperationException("Finish called on UnloadableTypeWrapper: " + Name);
} }
} }
@ -1948,7 +1948,7 @@ class DynamicTypeWrapper : TypeWrapper
} }
MethodBuilder mb = typeBuilder.DefineMethod(name, attribs, retType, args); MethodBuilder mb = typeBuilder.DefineMethod(name, attribs, retType, args);
method = mb; method = mb;
// since Java constructors (and static intializers?) aren't allowed to be synchronized, we only check this here // since Java constructors (and static intializers) aren't allowed to be synchronized, we only check this here
if(m.IsSynchronized) if(m.IsSynchronized)
{ {
mb.SetImplementationFlags(method.GetMethodImplementationFlags() | MethodImplAttributes.Synchronized); mb.SetImplementationFlags(method.GetMethodImplementationFlags() | MethodImplAttributes.Synchronized);
@ -1963,8 +1963,9 @@ class DynamicTypeWrapper : TypeWrapper
if(retTypeWrapper.IsUnloadable) if(retTypeWrapper.IsUnloadable)
{ {
CustomAttributeBuilder attrib = new CustomAttributeBuilder(typeof(UnloadableTypeAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { retTypeWrapper.Name }); CustomAttributeBuilder attrib = new CustomAttributeBuilder(typeof(UnloadableTypeAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { retTypeWrapper.Name });
// TODO DefineParameter(0, ...) throws an exception, even though this looks like the way to do it... // NOTE since DefineParameter(0, ...) throws an exception (bug in .NET, I believe),
((MethodBuilder)method).DefineParameter(0, ParameterAttributes.None, null).SetCustomAttribute(attrib); // we attach the attribute to the method instead of the return value
((MethodBuilder)method).SetCustomAttribute(attrib);
} }
for(int i = 0; i < argTypeWrappers.Length; i++) for(int i = 0; i < argTypeWrappers.Length; i++)
{ {
@ -2150,12 +2151,27 @@ class RemappedTypeWrapper : TypeWrapper
{ {
binding |= BindingFlags.Instance; binding |= BindingFlags.Instance;
} }
Type t = this.type;
if(method.redirect.Class != null) if(method.redirect.Class != null)
{ {
t = Type.GetType(method.redirect.Class, true); TypeWrapper tw = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(method.redirect.Class);
if(tw is DynamicTypeWrapper)
{
MethodWrapper mw1 = tw.GetMethodWrapper(redir, false);
if(mw1 == null)
{
Console.WriteLine("method not found: " + tw.Name + "." + redir.Name + redir.Signature);
}
redirect = mw1.GetMethod();
}
else
{
redirect = tw.Type.GetMethod(name, binding, null, CallingConventions.Standard, redir.ArgTypes, null);
}
}
else
{
redirect = this.type.GetMethod(name, binding, null, CallingConventions.Standard, redir.ArgTypes, null);
} }
redirect = t.GetMethod(name, binding, null, CallingConventions.Standard, redir.ArgTypes, null);
if(redirect == null) if(redirect == null)
{ {
throw new InvalidOperationException("remapping method: " + name + sig + " not found"); throw new InvalidOperationException("remapping method: " + name + sig + " not found");
@ -2196,11 +2212,7 @@ class RemappedTypeWrapper : TypeWrapper
} }
} }
} }
// NOTE we abuse MethodWrapper.Create here to construct the emitters for us MethodWrapper.CreateEmitters(overrideMethod, redirect, ref invokespecial, ref invokevirtual, ref newopc);
MethodWrapper temp = MethodWrapper.Create(this, md, overrideMethod, redirect, modifiers);
newopc = temp.EmitNewobj;
invokespecial = temp.EmitCall;
invokevirtual = temp.EmitCallvirt;
} }
else else
{ {
@ -2234,6 +2246,14 @@ class RemappedTypeWrapper : TypeWrapper
invokevirtual = CodeEmitter.Create(OpCodes.Callvirt, (MethodInfo)overrideMethod); invokevirtual = CodeEmitter.Create(OpCodes.Callvirt, (MethodInfo)overrideMethod);
} }
} }
// HACK MethodWrapper doesn't accept a MethodBuilder, so we have to blank it out, note
// that this means that reflection won't work on this method, so we have to add support
// for that
// TODO support reflection
if(redirect is MethodBuilder)
{
redirect = null;
}
MethodWrapper mw = new MethodWrapper(this, md, overrideMethod, redirect, modifiers); MethodWrapper mw = new MethodWrapper(this, md, overrideMethod, redirect, modifiers);
mw.EmitNewobj = newopc; mw.EmitNewobj = newopc;
mw.EmitCall = invokespecial; mw.EmitCall = invokespecial;
@ -2312,19 +2332,42 @@ class RemappedTypeWrapper : TypeWrapper
{ {
binding |= BindingFlags.Instance; binding |= BindingFlags.Instance;
} }
Type t = this.type; MethodBase redirect = null;
if(constructor.redirect.Class != null) if(constructor.redirect.Class != null)
{ {
t = Type.GetType(constructor.redirect.Class, true); TypeWrapper tw = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(constructor.redirect.Class);
} if(tw is DynamicTypeWrapper)
MethodBase redirect = null; {
if(constructor.redirect.Name != null) MethodDescriptor md1 = new MethodDescriptor(GetClassLoader(), constructor.redirect.Name != null ? constructor.redirect.Name : "<init>", sig);
{ MethodWrapper mw1 = tw.GetMethodWrapper(md1, false);
redirect = t.GetMethod(constructor.redirect.Name, binding, null, CallingConventions.Standard, redir.ArgTypes, null); if(mw1 == null)
{
Console.WriteLine("constructor not found: " + tw.Name + "." + redir.Name + redir.Signature);
}
redirect = mw1.GetMethod();
}
else
{
if(constructor.redirect.Name != null)
{
redirect = tw.Type.GetMethod(constructor.redirect.Name, binding, null, CallingConventions.Standard, redir.ArgTypes, null);
}
else
{
redirect = tw.Type.GetConstructor(binding, null, CallingConventions.Standard, redir.ArgTypes, null);
}
}
} }
else else
{ {
redirect = t.GetConstructor(binding, null, CallingConventions.Standard, redir.ArgTypes, null); if(constructor.redirect.Name != null)
{
redirect = this.type.GetMethod(constructor.redirect.Name, binding, null, CallingConventions.Standard, redir.ArgTypes, null);
}
else
{
redirect = this.type.GetConstructor(binding, null, CallingConventions.Standard, redir.ArgTypes, null);
}
} }
if(redirect == null) if(redirect == null)
{ {
@ -2410,10 +2453,14 @@ class RemappedTypeWrapper : TypeWrapper
{ {
throw new InvalidOperationException("remapping method: " + name + sig + " not found"); throw new InvalidOperationException("remapping method: " + name + sig + " not found");
} }
// TODO ensure that return type for redirected method matches with field type, or emit a castclass
FieldWrapper fw = new FieldWrapper(this, fieldName, fieldSig, modifiers); FieldWrapper fw = new FieldWrapper(this, fieldName, fieldSig, modifiers);
fw.EmitGet = CodeEmitter.Create(OpCodes.Call, method); fw.EmitGet = CodeEmitter.Create(OpCodes.Call, method);
fw.EmitSet = null; fw.EmitSet = null;
// ensure that return type for redirected method matches with field type, or emit a castclass
if(!field.redirect.Sig.EndsWith(fieldSig))
{
fw.EmitGet += new CastEmitter("()" + fieldSig);
}
AddField(fw); AddField(fw);
} }
} }
@ -3525,33 +3572,38 @@ sealed class MethodWrapper
throw new InvalidOperationException(); throw new InvalidOperationException();
} }
MethodWrapper wrapper = new MethodWrapper(declaringType, md, originalMethod, method, modifiers); MethodWrapper wrapper = new MethodWrapper(declaringType, md, originalMethod, method, modifiers);
CreateEmitters(originalMethod, method, ref wrapper.EmitCall, ref wrapper.EmitCallvirt, ref wrapper.EmitNewobj);
return wrapper;
}
internal static void CreateEmitters(MethodBase originalMethod, MethodBase method, ref CodeEmitter call, ref CodeEmitter callvirt, ref CodeEmitter newobj)
{
if(method is ConstructorInfo) if(method is ConstructorInfo)
{ {
wrapper.EmitCall = CodeEmitter.Create(OpCodes.Call, (ConstructorInfo)method); call = CodeEmitter.Create(OpCodes.Call, (ConstructorInfo)method);
wrapper.EmitCallvirt = null; callvirt = null;
wrapper.EmitNewobj = CodeEmitter.Create(OpCodes.Newobj, (ConstructorInfo)method); newobj = CodeEmitter.Create(OpCodes.Newobj, (ConstructorInfo)method);
} }
else else
{ {
wrapper.EmitCall = CodeEmitter.Create(OpCodes.Call, (MethodInfo)method); call = CodeEmitter.Create(OpCodes.Call, (MethodInfo)method);
if(originalMethod != null && originalMethod != method) if(originalMethod != null && originalMethod != method)
{ {
// if we're calling a virtual method that is redirected, that overrides an already // if we're calling a virtual method that is redirected, that overrides an already
// existing method, we have to call it virtually, instead of redirecting // existing method, we have to call it virtually, instead of redirecting
wrapper.EmitCallvirt = CodeEmitter.Create(OpCodes.Callvirt, (MethodInfo)originalMethod); callvirt = CodeEmitter.Create(OpCodes.Callvirt, (MethodInfo)originalMethod);
} }
else if(method.IsStatic) else if(method.IsStatic)
{ {
// because of redirection, it can be legal to call a static method with invokevirtual // because of redirection, it can be legal to call a static method with invokevirtual
wrapper.EmitCallvirt = CodeEmitter.Create(OpCodes.Call, (MethodInfo)method); callvirt = CodeEmitter.Create(OpCodes.Call, (MethodInfo)method);
} }
else else
{ {
wrapper.EmitCallvirt = CodeEmitter.Create(OpCodes.Callvirt, (MethodInfo)method); callvirt = CodeEmitter.Create(OpCodes.Callvirt, (MethodInfo)method);
} }
wrapper.EmitNewobj = CodeEmitter.Create(OpCodes.Call, (MethodInfo)method); newobj = CodeEmitter.Create(OpCodes.Call, (MethodInfo)method);
} }
return wrapper;
} }
internal MethodWrapper(TypeWrapper declaringType, MethodDescriptor md, MethodBase originalMethod, MethodBase method, Modifiers modifiers) internal MethodWrapper(TypeWrapper declaringType, MethodDescriptor md, MethodBase originalMethod, MethodBase method, Modifiers modifiers)

Просмотреть файл

@ -918,13 +918,17 @@ namespace NativeCode.java
public static object loadBootstrapClass(string name, bool initialize) public static object loadBootstrapClass(string name, bool initialize)
{ {
TypeWrapper type = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(name); TypeWrapper type = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedNameFast(name);
type.Finish(); if(type != null)
if(initialize)
{ {
RuntimeHelpers.RunClassConstructor(type.Type.TypeHandle); if(initialize)
{
type.Finish();
RuntimeHelpers.RunClassConstructor(type.Type.TypeHandle);
}
return getClassFromWrapper(type);
} }
return getClassFromType(type.Type); return null;
} }
internal static object CreateInstance(Type type, TypeWrapper wrapper) internal static object CreateInstance(Type type, TypeWrapper wrapper)
@ -1685,8 +1689,13 @@ namespace NativeCode.java
{ {
public static string getDefaultTimeZoneId() public static string getDefaultTimeZoneId()
{ {
// HACK return null, classpath then assumes GMT, which is fine by me, for the time being NetSystem.TimeZone currentTimeZone = NetSystem.TimeZone.CurrentTimeZone;
return null; NetSystem.TimeSpan timeSpan = currentTimeZone.GetUtcOffset(DateTime.Now);
int hours = timeSpan.Hours;
int mins = timeSpan.Minutes;
return "GMT" + hours + ":" + mins;
} }
} }
} }

Просмотреть файл

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<!-- <!--
Copyright (C) 2002 Jeroen Frijters Copyright (C) 2002, 2003 Jeroen Frijters
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -109,7 +109,7 @@
<constructor sig="([CII)V" modifiers="public" /> <constructor sig="([CII)V" modifiers="public" />
<!-- Package private constructor, that we redirect to static helper --> <!-- Package private constructor, that we redirect to static helper -->
<constructor sig="([CIIZ)V" modifiers=""> <constructor sig="([CIIZ)V" modifiers="">
<redirect class="StringHelper" name="NewString" type="static" sig="([CIIZ)Ljava/lang/String;" /> <redirect class="java.lang.StringHelper" name="NewString" type="static" sig="([CIIZ)Ljava/lang/String;" />
</constructor> </constructor>
<constructor sig="(Ljava/lang/String;)V" modifiers="public"> <constructor sig="(Ljava/lang/String;)V" modifiers="public">
<redirect class="System.String" name="Copy" type="static" sig="(Ljava/lang/String;)Ljava/lang/String;" /> <redirect class="System.String" name="Copy" type="static" sig="(Ljava/lang/String;)Ljava/lang/String;" />
@ -118,22 +118,22 @@
<redirect class="System.Text.StringBuilder" name="ToString" sig="()Ljava/lang/String;" /> <redirect class="System.Text.StringBuilder" name="ToString" sig="()Ljava/lang/String;" />
</constructor> </constructor>
<constructor sig="([B)V" modifiers="public"> <constructor sig="([B)V" modifiers="public">
<redirect class="StringHelper" name="NewString" type="static" sig="([B)Ljava/lang/String;" /> <redirect class="java.lang.StringHelper" name="NewString" type="static" sig="([B)Ljava/lang/String;" />
</constructor> </constructor>
<constructor sig="([BI)V" modifiers="public"> <constructor sig="([BI)V" modifiers="public">
<redirect class="StringHelper" name="NewString" type="static" sig="([BI)Ljava/lang/String;" /> <redirect class="java.lang.StringHelper" name="NewString" type="static" sig="([BI)Ljava/lang/String;" />
</constructor> </constructor>
<constructor sig="([BII)V" modifiers="public"> <constructor sig="([BII)V" modifiers="public">
<redirect class="StringHelper" name="NewString" type="static" sig="([BII)Ljava/lang/String;" /> <redirect class="java.lang.StringHelper" name="NewString" type="static" sig="([BII)Ljava/lang/String;" />
</constructor> </constructor>
<constructor sig="([BIII)V" modifiers="public"> <constructor sig="([BIII)V" modifiers="public">
<redirect class="StringHelper" name="NewString" type="static" sig="([BIII)Ljava/lang/String;" /> <redirect class="java.lang.StringHelper" name="NewString" type="static" sig="([BIII)Ljava/lang/String;" />
</constructor> </constructor>
<constructor sig="([BLjava/lang/String;)V" modifiers="public"> <constructor sig="([BLjava/lang/String;)V" modifiers="public">
<redirect class="StringHelper" name="NewString" type="static" sig="([BLjava/lang/String;)Ljava/lang/String;" /> <redirect class="java.lang.StringHelper" name="NewString" type="static" sig="([BLjava/lang/String;)Ljava/lang/String;" />
</constructor> </constructor>
<constructor sig="([BIILjava/lang/String;)V" modifiers="public"> <constructor sig="([BIILjava/lang/String;)V" modifiers="public">
<redirect class="StringHelper" name="NewString" type="static" sig="([BIILjava/lang/String;)Ljava/lang/String;" /> <redirect class="java.lang.StringHelper" name="NewString" type="static" sig="([BIILjava/lang/String;)Ljava/lang/String;" />
</constructor> </constructor>
<method name="hashCode" sig="()I" modifiers="public"> <method name="hashCode" sig="()I" modifiers="public">
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;)I" /> <redirect class="StringHelper" type="static" sig="(Ljava/lang/String;)I" />
@ -220,52 +220,52 @@
<redirect name="EndsWith" /> <redirect name="EndsWith" />
</method> </method>
<method name="toUpperCase" sig="()Ljava/lang/String;" modifiers="public"> <method name="toUpperCase" sig="()Ljava/lang/String;" modifiers="public">
<redirect name="ToUpper" /> <redirect class="java.lang.StringHelper" type="static" sig="(Ljava/lang/String;)Ljava/lang/String;" />
</method> </method>
<method name="toUpperCase" sig="(Ljava/util/Locale;)Ljava/lang/String;" modifiers="public"> <method name="toUpperCase" sig="(Ljava/util/Locale;)Ljava/lang/String;" modifiers="public">
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;" /> <redirect class="java.lang.StringHelper" type="static" sig="(Ljava/lang/String;Ljava/util/Locale;)Ljava/lang/String;" />
</method> </method>
<method name="toLowerCase" sig="()Ljava/lang/String;" modifiers="public"> <method name="toLowerCase" sig="()Ljava/lang/String;" modifiers="public">
<redirect name="ToLower" /> <redirect class="java.lang.StringHelper" type="static" sig="(Ljava/lang/String;)Ljava/lang/String;" />
</method> </method>
<method name="toLowerCase" sig="(Ljava/util/Locale;)Ljava/lang/String;" modifiers="public"> <method name="toLowerCase" sig="(Ljava/util/Locale;)Ljava/lang/String;" modifiers="public">
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;" /> <redirect class="java.lang.StringHelper" type="static" sig="(Ljava/lang/String;Ljava/util/Locale;)Ljava/lang/String;" />
</method> </method>
<method name="compareToIgnoreCase" sig="(Ljava/lang/String;)I" modifiers="public"> <method name="compareToIgnoreCase" sig="(Ljava/lang/String;)I" modifiers="public">
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;Ljava/lang/String;)I" /> <redirect class="java.lang.StringHelper" type="static" sig="(Ljava/lang/String;Ljava/lang/String;)I" />
</method> </method>
<method name="equalsIgnoreCase" sig="(Ljava/lang/String;)Z" modifiers="public"> <method name="equalsIgnoreCase" sig="(Ljava/lang/String;)Z" modifiers="public">
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;Ljava/lang/String;)Z" /> <redirect class="java.lang.StringHelper" type="static" sig="(Ljava/lang/String;Ljava/lang/String;)Z" />
</method> </method>
<method name="intern" sig="()Ljava/lang/String;" modifiers="public"> <method name="intern" sig="()Ljava/lang/String;" modifiers="public">
<redirect type="static" name="Intern" sig="(Ljava/lang/String;)Ljava/lang/String;" /> <redirect type="static" name="Intern" sig="(Ljava/lang/String;)Ljava/lang/String;" />
</method> </method>
<method name="compareTo" sig="(Ljava/lang/String;)I" modifiers="public"> <method name="compareTo" sig="(Ljava/lang/String;)I" modifiers="public">
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;Ljava/lang/String;)I" /> <redirect class="java.lang.StringHelper" type="static" sig="(Ljava/lang/String;Ljava/lang/String;)I" />
</method> </method>
<method name="replace" sig="(CC)Ljava/lang/String;" modifiers="public"> <method name="replace" sig="(CC)Ljava/lang/String;" modifiers="public">
<redirect name="Replace" /> <redirect name="Replace" />
</method> </method>
<method name="getBytes" sig="()[B" modifiers="public"> <method name="getBytes" sig="()[B" modifiers="public">
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;)[B" /> <redirect class="java.lang.StringHelper" type="static" sig="(Ljava/lang/String;)[B" />
</method> </method>
<method name="getBytes" sig="(Ljava/lang/String;)[B" modifiers="public"> <method name="getBytes" sig="(Ljava/lang/String;)[B" modifiers="public">
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;Ljava/lang/String;)[B" /> <redirect class="java.lang.StringHelper" type="static" sig="(Ljava/lang/String;Ljava/lang/String;)[B" />
</method> </method>
<method name="subSequence" sig="(II)Ljava/lang/CharSequence;" modifiers="public"> <method name="subSequence" sig="(II)Ljava/lang/CharSequence;" modifiers="public">
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;II)Ljava/lang/Object;" /> <redirect class="StringHelper" type="static" sig="(Ljava/lang/String;II)Ljava/lang/Object;" />
</method> </method>
<method name="trim" sig="()Ljava/lang/String;" modifiers="public"> <method name="trim" sig="()Ljava/lang/String;" modifiers="public">
<redirect name="Trim" /> <redirect class="java.lang.StringHelper" type="static" sig="(Ljava/lang/String;)Ljava/lang/String;" />
</method> </method>
<method name="regionMatches" sig="(ZILjava/lang/String;II)Z" modifiers="public"> <method name="regionMatches" sig="(ZILjava/lang/String;II)Z" modifiers="public">
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;ZILjava/lang/String;II)Z" /> <redirect class="java.lang.StringHelper" type="static" sig="(Ljava/lang/String;ZILjava/lang/String;II)Z" />
</method> </method>
<method name="regionMatches" sig="(ILjava/lang/String;II)Z" modifiers="public"> <method name="regionMatches" sig="(ILjava/lang/String;II)Z" modifiers="public">
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;ILjava/lang/String;II)Z" /> <redirect class="java.lang.StringHelper" type="static" sig="(Ljava/lang/String;ILjava/lang/String;II)Z" />
</method> </method>
<method name="getBytes" sig="(II[BI)V" modifiers="public"> <method name="getBytes" sig="(II[BI)V" modifiers="public">
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;II[BI)V" /> <redirect class="java.lang.StringHelper" type="static" sig="(Ljava/lang/String;II[BI)V" />
</method> </method>
<method name="concat" sig="(Ljava/lang/String;)Ljava/lang/String;" modifiers="public"> <method name="concat" sig="(Ljava/lang/String;)Ljava/lang/String;" modifiers="public">
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;" /> <redirect class="StringHelper" type="static" sig="(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;" />
@ -280,6 +280,9 @@
<newobj class="System.String" name=".ctor" sig="([CII)V" /> <newobj class="System.String" name=".ctor" sig="([CII)V" />
</invokestatic> </invokestatic>
</method> </method>
<field name="CASE_INSENSITIVE_ORDER" sig="Ljava/util/Comparator;" modifiers="public static final">
<redirect class="StringHelper" type="static" name="GetCaseInsensitiveOrder" sig="()Ljava/lang/Object;" />
</field>
<!-- NOTE we're redirecting fields to static methods here! <!-- NOTE we're redirecting fields to static methods here!
NOTE only reading fields can be redirected NOTE only reading fields can be redirected
--> -->

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -34,6 +34,7 @@ public class JVM
private static bool debug = false; private static bool debug = false;
private static bool noJniStubs = false; private static bool noJniStubs = false;
private static bool isStaticCompiler = false; private static bool isStaticCompiler = false;
private static bool logClassLoadFailures = false;
private static IJniProvider jniProvider; private static IJniProvider jniProvider;
public static bool Debug public static bool Debug
@ -64,6 +65,18 @@ public class JVM
} }
} }
public static bool LogClassLoadFailures
{
get
{
return logClassLoadFailures;
}
set
{
logClassLoadFailures = value;
}
}
public static bool CleanStackTraces public static bool CleanStackTraces
{ {
get get
@ -222,7 +235,7 @@ public class JVM
{ {
Assembly.LoadFrom(r); Assembly.LoadFrom(r);
} }
Console.WriteLine("Loading remapped types"); Console.WriteLine("Loading remapped types (1)");
loader.LoadRemappedTypes(); loader.LoadRemappedTypes();
Console.WriteLine("Compiling class files (1)"); Console.WriteLine("Compiling class files (1)");
foreach(string s in h.Keys) foreach(string s in h.Keys)
@ -253,6 +266,8 @@ public class JVM
loader.SetMain(method, target); loader.SetMain(method, target);
} }
} }
Console.WriteLine("Loading remapped types (2)");
loader.LoadRemappedTypesStep2();
Console.WriteLine("Compiling class files (2)"); Console.WriteLine("Compiling class files (2)");
loader.AddResources(resources); loader.AddResources(resources);
loader.Save(); loader.Save();

Просмотреть файл

@ -458,6 +458,10 @@ namespace ikvm.awt
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool requestFocus(java.awt.Component source, bool bool1, bool bool2, long x)
{
throw new NotImplementedException();
}
public void reshape(int x, int y, int width, int height) public void reshape(int x, int y, int width, int height)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
@ -524,6 +528,62 @@ namespace ikvm.awt
{ {
Console.WriteLine("NOTE: NetComponentPeer.setEventMask not implemented"); Console.WriteLine("NOTE: NetComponentPeer.setEventMask not implemented");
} }
public bool isObscured()
{
throw new NotImplementedException();
}
public bool canDetermineObscurity()
{
throw new NotImplementedException();
}
public void coalescePaintEvent(java.awt.@event.PaintEvent e)
{
throw new NotImplementedException();
}
public void updateCursorImmediately()
{
throw new NotImplementedException();
}
public VolatileImage createVolatileImage(int width, int height)
{
throw new NotImplementedException();
}
public bool handlesWheelScrolling()
{
throw new NotImplementedException();
}
public void createBuffers(int x, java.awt.BufferCapabilities capabilities)
{
throw new NotImplementedException();
}
public java.awt.Image getBackBuffer()
{
throw new NotImplementedException();
}
public void flip(java.awt.BufferCapabilities.FlipContents contents)
{
throw new NotImplementedException();
}
public void destroyBuffers()
{
throw new NotImplementedException();
}
public bool isFocusable()
{
// TODO
return true;
}
} }
class NetButtonPeer : NetComponentPeer, ButtonPeer class NetButtonPeer : NetComponentPeer, ButtonPeer
@ -632,6 +692,18 @@ namespace ikvm.awt
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public long filterEvents(long filter)
{
throw new NotImplementedException();
}
public int getIndexAtPoint(int x, int y)
{
throw new NotImplementedException();
}
public java.awt.Rectangle getCharacterBounds(int pos)
{
throw new NotImplementedException();
}
} }
class NetTextFieldPeer : NetTextComponentPeer, TextFieldPeer class NetTextFieldPeer : NetTextComponentPeer, TextFieldPeer
@ -757,6 +829,18 @@ namespace ikvm.awt
{ {
Console.WriteLine("NOTE: NetContainerPeer.endValidate not implemented"); Console.WriteLine("NOTE: NetContainerPeer.endValidate not implemented");
} }
public void beginLayout()
{
throw new NotImplementedException();
}
public void endLayout()
{
throw new NotImplementedException();
}
public bool isPaintPending()
{
throw new NotImplementedException();
}
} }
class NetPanelPeer : NetContainerPeer, PanelPeer class NetPanelPeer : NetContainerPeer, PanelPeer
@ -846,5 +930,17 @@ namespace ikvm.awt
// TODO use control.Invoke // TODO use control.Invoke
return new java.awt.Insets(0, 0, control.Height - client.Height, control.Width - client.Width); return new java.awt.Insets(0, 0, control.Height - client.Height, control.Width - client.Width);
} }
public int getState()
{
throw new NotImplementedException();
}
public void setState(int state)
{
throw new NotImplementedException();
}
public void setMaximizedBounds(java.awt.Rectangle r)
{
throw new NotImplementedException();
}
} }
} }

Просмотреть файл

@ -2,11 +2,9 @@ C:\ikvm\classpath\ikvm\lang\DotNetProcess.java
C:\ikvm\classpath\gnu\classpath\Configuration.java C:\ikvm\classpath\gnu\classpath\Configuration.java
C:\ikvm\classpath\gnu\java\net\protocol\ikvmres\Handler.java C:\ikvm\classpath\gnu\java\net\protocol\ikvmres\Handler.java
C:\ikvm\classpath\java\io\FileDescriptor.java C:\ikvm\classpath\java\io\FileDescriptor.java
C:\ikvm\classpath\java\io\FileInputStream.java
C:\ikvm\classpath\java\io\FileOutputStream.java
C:\ikvm\classpath\java\io\RandomAccessFile.java
C:\ikvm\classpath\java\lang\Thread.java C:\ikvm\classpath\java\lang\Thread.java
C:\ikvm\classpath\java\lang\Class.java C:\ikvm\classpath\java\lang\Class.java
C:\ikvm\classpath\java\lang\StringHelper.java
C:\ikvm\classpath\java\lang\VMClassLoader.java C:\ikvm\classpath\java\lang\VMClassLoader.java
C:\ikvm\classpath\java\lang\reflect\Constructor.java C:\ikvm\classpath\java\lang\reflect\Constructor.java
C:\ikvm\classpath\java\lang\reflect\Method.java C:\ikvm\classpath\java\lang\reflect\Method.java
@ -220,6 +218,7 @@ C:\classpath\gnu\java\nio\CharBufferImpl.java
C:\classpath\gnu\java\nio\DatagramChannelImpl.java C:\classpath\gnu\java\nio\DatagramChannelImpl.java
C:\classpath\gnu\java\nio\DoubleBufferImpl.java C:\classpath\gnu\java\nio\DoubleBufferImpl.java
C:\classpath\gnu\java\nio\FileChannelImpl.java C:\classpath\gnu\java\nio\FileChannelImpl.java
C:\classpath\gnu\java\nio\FileLockImpl.java
C:\classpath\gnu\java\nio\FloatBufferImpl.java C:\classpath\gnu\java\nio\FloatBufferImpl.java
C:\classpath\gnu\java\nio\IntBufferImpl.java C:\classpath\gnu\java\nio\IntBufferImpl.java
C:\classpath\gnu\java\nio\LongBufferImpl.java C:\classpath\gnu\java\nio\LongBufferImpl.java
@ -429,6 +428,7 @@ C:\classpath\java\awt\datatransfer\Transferable.java
C:\classpath\java\awt\datatransfer\UnsupportedFlavorException.java C:\classpath\java\awt\datatransfer\UnsupportedFlavorException.java
C:\classpath\java\awt\dnd\Autoscroll.java C:\classpath\java\awt\dnd\Autoscroll.java
C:\classpath\java\awt\dnd\DnDConstants.java C:\classpath\java\awt\dnd\DnDConstants.java
C:\classpath\java\awt\dnd\DnDEventMulticaster.java
C:\classpath\java\awt\dnd\DragGestureEvent.java C:\classpath\java\awt\dnd\DragGestureEvent.java
C:\classpath\java\awt\dnd\DragGestureListener.java C:\classpath\java\awt\dnd\DragGestureListener.java
C:\classpath\java\awt\dnd\DragGestureRecognizer.java C:\classpath\java\awt\dnd\DragGestureRecognizer.java
@ -451,6 +451,7 @@ C:\classpath\java\awt\dnd\InvalidDnDOperationException.java
C:\classpath\java\awt\dnd\MouseDragGestureRecognizer.java C:\classpath\java\awt\dnd\MouseDragGestureRecognizer.java
C:\classpath\java\awt\dnd\peer\DragSourceContextPeer.java C:\classpath\java\awt\dnd\peer\DragSourceContextPeer.java
C:\classpath\java\awt\dnd\peer\DropTargetContextPeer.java C:\classpath\java\awt\dnd\peer\DropTargetContextPeer.java
C:\classpath\java\awt\dnd\peer\DropTargetPeer.java
C:\classpath\java\awt\event\ActionEvent.java C:\classpath\java\awt\event\ActionEvent.java
C:\classpath\java\awt\event\ActionListener.java C:\classpath\java\awt\event\ActionListener.java
C:\classpath\java\awt\event\AdjustmentEvent.java C:\classpath\java\awt\event\AdjustmentEvent.java
@ -494,7 +495,23 @@ C:\classpath\java\awt\event\WindowEvent.java
C:\classpath\java\awt\event\WindowFocusListener.java C:\classpath\java\awt\event\WindowFocusListener.java
C:\classpath\java\awt\event\WindowListener.java C:\classpath\java\awt\event\WindowListener.java
C:\classpath\java\awt\event\WindowStateListener.java C:\classpath\java\awt\event\WindowStateListener.java
C:\classpath\java\awt\font\FontRenderContext.java
C:\classpath\java\awt\font\GlyphJustificationInfo.java
C:\classpath\java\awt\font\GlyphMetrics.java
C:\classpath\java\awt\font\GlyphVector.java
C:\classpath\java\awt\font\GraphicAttribute.java
C:\classpath\java\awt\font\ImageGraphicAttribute.java
C:\classpath\java\awt\font\LineBreakMeasurer.java
C:\classpath\java\awt\font\LineMetrics.java
C:\classpath\java\awt\font\MultipleMaster.java
C:\classpath\java\awt\font\NumericShaper.java
C:\classpath\java\awt\font\OpenType.java
C:\classpath\java\awt\font\ShapeGraphicAttribute.java
C:\classpath\java\awt\font\TextAttribute.java
C:\classpath\java\awt\font\TextHitInfo.java C:\classpath\java\awt\font\TextHitInfo.java
C:\classpath\java\awt\font\TextLayout.java
C:\classpath\java\awt\font\TextMeasurer.java
C:\classpath\java\awt\font\TransformAttribute.java
C:\classpath\java\awt\geom\AffineTransform.java C:\classpath\java\awt\geom\AffineTransform.java
C:\classpath\java\awt\geom\Arc2D.java C:\classpath\java\awt\geom\Arc2D.java
C:\classpath\java\awt\geom\Area.java C:\classpath\java\awt\geom\Area.java
@ -581,6 +598,7 @@ C:\classpath\java\awt\peer\MenuItemPeer.java
C:\classpath\java\awt\peer\MenuPeer.java C:\classpath\java\awt\peer\MenuPeer.java
C:\classpath\java\awt\peer\PanelPeer.java C:\classpath\java\awt\peer\PanelPeer.java
C:\classpath\java\awt\peer\PopupMenuPeer.java C:\classpath\java\awt\peer\PopupMenuPeer.java
C:\classpath\java\awt\peer\RobotPeer.java
C:\classpath\java\awt\peer\ScrollbarPeer.java C:\classpath\java\awt\peer\ScrollbarPeer.java
C:\classpath\java\awt\peer\ScrollPanePeer.java C:\classpath\java\awt\peer\ScrollPanePeer.java
C:\classpath\java\awt\peer\TextAreaPeer.java C:\classpath\java\awt\peer\TextAreaPeer.java
@ -641,6 +659,8 @@ C:\classpath\java\beans\beancontext\BeanContextServiceRevokedEvent.java
C:\classpath\java\beans\beancontext\BeanContextServiceRevokedListener.java C:\classpath\java\beans\beancontext\BeanContextServiceRevokedListener.java
C:\classpath\java\beans\beancontext\BeanContextServices.java C:\classpath\java\beans\beancontext\BeanContextServices.java
C:\classpath\java\beans\beancontext\BeanContextServicesListener.java C:\classpath\java\beans\beancontext\BeanContextServicesListener.java
C:\classpath\java\beans\beancontext\BeanContextServicesSupport.java
C:\classpath\java\beans\beancontext\BeanContextSupport.java
C:\classpath\java\io\BufferedInputStream.java C:\classpath\java\io\BufferedInputStream.java
C:\classpath\java\io\BufferedOutputStream.java C:\classpath\java\io\BufferedOutputStream.java
C:\classpath\java\io\BufferedReader.java C:\classpath\java\io\BufferedReader.java
@ -658,8 +678,10 @@ C:\classpath\java\io\EOFException.java
C:\classpath\java\io\Externalizable.java C:\classpath\java\io\Externalizable.java
C:\classpath\java\io\File.java C:\classpath\java\io\File.java
C:\classpath\java\io\FileFilter.java C:\classpath\java\io\FileFilter.java
C:\classpath\java\io\FileInputStream.java
C:\classpath\java\io\FilenameFilter.java C:\classpath\java\io\FilenameFilter.java
C:\classpath\java\io\FileNotFoundException.java C:\classpath\java\io\FileNotFoundException.java
C:\classpath\java\io\FileOutputStream.java
C:\classpath\java\io\FilePermission.java C:\classpath\java\io\FilePermission.java
C:\classpath\java\io\FileReader.java C:\classpath\java\io\FileReader.java
C:\classpath\java\io\FileWriter.java C:\classpath\java\io\FileWriter.java
@ -697,6 +719,7 @@ C:\classpath\java\io\PrintStream.java
C:\classpath\java\io\PrintWriter.java C:\classpath\java\io\PrintWriter.java
C:\classpath\java\io\PushbackInputStream.java C:\classpath\java\io\PushbackInputStream.java
C:\classpath\java\io\PushbackReader.java C:\classpath\java\io\PushbackReader.java
C:\classpath\java\io\RandomAccessFile.java
C:\classpath\java\io\Reader.java C:\classpath\java\io\Reader.java
C:\classpath\java\io\SequenceInputStream.java C:\classpath\java\io\SequenceInputStream.java
C:\classpath\java\io\Serializable.java C:\classpath\java\io\Serializable.java
@ -1081,6 +1104,7 @@ C:\classpath\java\security\interfaces\DSAParams.java
C:\classpath\java\security\interfaces\DSAPrivateKey.java C:\classpath\java\security\interfaces\DSAPrivateKey.java
C:\classpath\java\security\interfaces\DSAPublicKey.java C:\classpath\java\security\interfaces\DSAPublicKey.java
C:\classpath\java\security\interfaces\RSAKey.java C:\classpath\java\security\interfaces\RSAKey.java
C:\classpath\java\security\interfaces\RSAMultiPrimePrivateCrtKey.java
C:\classpath\java\security\interfaces\RSAPrivateCrtKey.java C:\classpath\java\security\interfaces\RSAPrivateCrtKey.java
C:\classpath\java\security\interfaces\RSAPrivateKey.java C:\classpath\java\security\interfaces\RSAPrivateKey.java
C:\classpath\java\security\interfaces\RSAPublicKey.java C:\classpath\java\security\interfaces\RSAPublicKey.java
@ -1093,7 +1117,10 @@ C:\classpath\java\security\spec\InvalidKeySpecException.java
C:\classpath\java\security\spec\InvalidParameterSpecException.java C:\classpath\java\security\spec\InvalidParameterSpecException.java
C:\classpath\java\security\spec\KeySpec.java C:\classpath\java\security\spec\KeySpec.java
C:\classpath\java\security\spec\PKCS8EncodedKeySpec.java C:\classpath\java\security\spec\PKCS8EncodedKeySpec.java
C:\classpath\java\security\spec\PSSParameterSpec.java
C:\classpath\java\security\spec\RSAKeyGenParameterSpec.java C:\classpath\java\security\spec\RSAKeyGenParameterSpec.java
C:\classpath\java\security\spec\RSAMultiPrimePrivateCrtKeySpec.java
C:\classpath\java\security\spec\RSAOtherPrimeInfo.java
C:\classpath\java\security\spec\RSAPrivateCrtKeySpec.java C:\classpath\java\security\spec\RSAPrivateCrtKeySpec.java
C:\classpath\java\security\spec\RSAPrivateKeySpec.java C:\classpath\java\security\spec\RSAPrivateKeySpec.java
C:\classpath\java\security\spec\RSAPublicKeySpec.java C:\classpath\java\security\spec\RSAPublicKeySpec.java
@ -1353,6 +1380,24 @@ C:\classpath\javax\naming\directory\NoSuchAttributeException.java
C:\classpath\javax\naming\directory\SchemaViolationException.java C:\classpath\javax\naming\directory\SchemaViolationException.java
C:\classpath\javax\naming\directory\SearchControls.java C:\classpath\javax\naming\directory\SearchControls.java
C:\classpath\javax\naming\directory\SearchResult.java C:\classpath\javax\naming\directory\SearchResult.java
C:\classpath\javax\naming\event\EventContext.java
C:\classpath\javax\naming\event\EventDirContext.java
C:\classpath\javax\naming\event\NamespaceChangeListener.java
C:\classpath\javax\naming\event\NamingEvent.java
C:\classpath\javax\naming\event\NamingExceptionEvent.java
C:\classpath\javax\naming\event\NamingListener.java
C:\classpath\javax\naming\event\ObjectChangeListener.java
C:\classpath\javax\naming\ldap\Control.java
C:\classpath\javax\naming\ldap\ControlFactory.java
C:\classpath\javax\naming\ldap\ExtendedRequest.java
C:\classpath\javax\naming\ldap\ExtendedResponse.java
C:\classpath\javax\naming\ldap\HasControls.java
C:\classpath\javax\naming\ldap\InitialLdapContext.java
C:\classpath\javax\naming\ldap\LdapContext.java
C:\classpath\javax\naming\ldap\LdapReferralException.java
C:\classpath\javax\naming\ldap\UnsolicitedNotification.java
C:\classpath\javax\naming\ldap\UnsolicitedNotificationEvent.java
C:\classpath\javax\naming\ldap\UnsolicitedNotificationListener.java
C:\classpath\javax\naming\spi\DirectoryManager.java C:\classpath\javax\naming\spi\DirectoryManager.java
C:\classpath\javax\naming\spi\DirObjectFactory.java C:\classpath\javax\naming\spi\DirObjectFactory.java
C:\classpath\javax\naming\spi\DirStateFactory.java C:\classpath\javax\naming\spi\DirStateFactory.java
@ -1699,9 +1744,9 @@ C:\classpath\javax\transaction\xa\XAResource.java
C:\classpath\javax\transaction\xa\Xid.java C:\classpath\javax\transaction\xa\Xid.java
C:\classpath\vm\reference\gnu\vm\stack\StackFrame.java C:\classpath\vm\reference\gnu\vm\stack\StackFrame.java
C:\classpath\vm\reference\gnu\vm\stack\StackTrace.java C:\classpath\vm\reference\gnu\vm\stack\StackTrace.java
C:\classpath\vm\reference\java\io\VMObjectStreamClass.java
C:\classpath\vm\reference\java\lang\Runtime.java C:\classpath\vm\reference\java\lang\Runtime.java
C:\classpath\vm\reference\java\lang\VMObject.java C:\classpath\vm\reference\java\lang\VMObject.java
C:\classpath\vm\reference\java\lang\VMSecurityManager.java C:\classpath\vm\reference\java\lang\VMSecurityManager.java
C:\classpath\vm\reference\java\lang\VMSystem.java C:\classpath\vm\reference\java\lang\VMSystem.java
C:\classpath\vm\reference\java\lang\VMThrowable.java C:\classpath\vm\reference\java\lang\VMThrowable.java
C:\classpath\vm\reference\java\io\VMObjectStreamClass.java

Просмотреть файл

@ -1,31 +1,54 @@
/* /* FileDescriptor.java -- Opaque file handle class
Copyright (C) 2002 Jeroen Frijters Copyright (C) 1998,2003 Free Software Foundation, Inc.
This software is provided 'as-is', without any express or implied This file is part of GNU Classpath.
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, GNU Classpath is free software; you can redistribute it and/or modify
including commercial applications, and to alter it and redistribute it it under the terms of the GNU General Public License as published by
freely, subject to the following restrictions: 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. */
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
*/
package java.io; package java.io;
import system.Console; import system.Console;
import system.io.*; import system.io.*;
/**
* This class represents an opaque file handle as a Java class. It should
* be used only to pass to other methods that expect an object of this
* type. No system specific information can be obtained from this object.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Jeroen Frijters (jeroen@sumatra.nl)
*/
public final class FileDescriptor public final class FileDescriptor
{ {
public static final FileDescriptor in = new FileDescriptor(Console.OpenStandardInput()); public static final FileDescriptor in = new FileDescriptor(Console.OpenStandardInput());
@ -96,43 +119,57 @@ public final class FileDescriptor
return path; return path;
} }
static final int Append = 0; // FileMode.Append, FileAccess.Write (FileOutputStream(append = true)) synchronized void open(String path, String mode) throws IOException
static final int Write = 1; // FileMode.Create, FileAccess.Write (FileOutputStream(append = false))
static final int Read = 2; // FileMode.Open, FileAccess.Read (FileInputStream, RandomAccessFile("r"))
static final int ReadWrite = 3; // FileMode.OpenOrCreate, FileAccess.ReadWrite (RandomAccessFile("rw"))
static FileDescriptor open(String name, int mode) throws FileNotFoundException
{ {
if(stream != null)
throw new IOException("FileDescriptor already open");
if ((path == null) || path.equals(""))
throw new IllegalArgumentException("Path cannot be null");
try try
{ {
int fileMode; int fileMode;
int fileAccess; int fileAccess;
switch(mode) if(mode.equals("r"))
{ {
case Append: fileMode = FileMode.Open;
fileMode = FileMode.Append; fileAccess = FileAccess.Read;
fileAccess = FileAccess.Write; }
break; else if(mode.equals("rw"))
case Write: {
fileMode = FileMode.Create; fileMode = FileMode.OpenOrCreate;
fileAccess = FileAccess.Write; fileAccess = FileAccess.ReadWrite;
break; }
case Read: else if(mode.equals("rws") || mode.equals("rwd"))
fileMode = FileMode.Open; {
fileAccess = FileAccess.Read; // TODO implement this
break; throw new IllegalArgumentException("rws and rwd not implemented");
case ReadWrite: //fileMode = FileMode.OpenOrCreate;
fileMode = FileMode.OpenOrCreate; //fileAccess = FileAccess.ReadWrite;
fileAccess = FileAccess.ReadWrite; }
break; else if(mode.equals("rwa"))
default: {
throw new Error("Invalid mode: " + mode); // TODO this is a bogus mode
fileMode = FileMode.Append;
fileAccess = FileAccess.ReadWrite;
}
else if(mode.equals("w"))
{
fileMode = FileMode.Create;
fileAccess = FileAccess.Write;
}
else if(mode.equals("a"))
{
fileMode = FileMode.Append;
fileAccess = FileAccess.Write;
}
else
{
throw new IllegalArgumentException("Invalid mode value: " + mode);
} }
if(false) throw new system.io.IOException(); if(false) throw new system.io.IOException();
if(false) throw new system.security.SecurityException(); if(false) throw new system.security.SecurityException();
if(false) throw new system.UnauthorizedAccessException(); if(false) throw new system.UnauthorizedAccessException();
FileStream fs = system.io.File.Open(demanglePath(name), fileMode, fileAccess, FileShare.ReadWrite); stream = system.io.File.Open(demanglePath(path), fileMode, fileAccess, FileShare.ReadWrite);
return new FileDescriptor(fs);
} }
catch(system.security.SecurityException x1) catch(system.security.SecurityException x1)
{ {
@ -153,9 +190,8 @@ public final class FileDescriptor
synchronized long getFilePointer() throws IOException synchronized long getFilePointer() throws IOException
{ {
if(stream == null) if(stream == null)
{ throw new IOException("Invalid FileDescriptor");
throw new IOException();
}
try try
{ {
if(false) throw new system.io.IOException(); if(false) throw new system.io.IOException();
@ -171,9 +207,8 @@ public final class FileDescriptor
synchronized long getLength() throws IOException synchronized long getLength() throws IOException
{ {
if(stream == null) if(stream == null)
{ throw new IOException("Invalid FileDescriptor");
throw new IOException();
}
try try
{ {
if(false) throw new system.io.IOException(); if(false) throw new system.io.IOException();
@ -186,16 +221,19 @@ public final class FileDescriptor
// TODO map al the other exceptions as well... // TODO map al the other exceptions as well...
} }
synchronized void setLength(long length) throws IOException synchronized void setLength(long len) throws IOException
{ {
if(stream == null) if(stream == null)
{ throw new IOException("Invalid FileDescriptor");
throw new IOException();
} if (len < 0)
throw new IllegalArgumentException("Length cannot be less than zero " +
len);
try try
{ {
if(false) throw new system.io.IOException(); if(false) throw new system.io.IOException();
stream.SetLength(length); stream.SetLength(len);
} }
catch(system.io.IOException x) catch(system.io.IOException x)
{ {
@ -204,16 +242,27 @@ public final class FileDescriptor
// TODO map al the other exceptions as well... // TODO map al the other exceptions as well...
} }
synchronized void seek(long pos) throws IOException static final int SET = SeekOrigin.Begin;
static final int CUR = SeekOrigin.Current;
static final int END = SeekOrigin.End;
synchronized long seek(long offset, int whence, boolean stopAtEof) throws IOException
{ {
if(stream == null) if(stream == null)
{ throw new IOException("Invalid FileDescriptor");
throw new IOException();
} if ((whence != SET) && (whence != CUR) && (whence != END))
throw new IllegalArgumentException("Invalid whence value: " + whence);
try try
{ {
if(false) throw new system.io.IOException(); if(false) throw new system.io.IOException();
stream.Seek(pos, SeekOrigin.Begin); long newpos = stream.Seek(offset, whence);
if(stopAtEof && newpos > stream.get_Length())
{
newpos = stream.Seek(0, SeekOrigin.End);
}
return newpos;
} }
catch(system.io.IOException x) catch(system.io.IOException x)
{ {
@ -222,16 +271,15 @@ public final class FileDescriptor
// TODO map al the other exceptions as well... // TODO map al the other exceptions as well...
} }
synchronized int read(byte[] buf, int offset, int length) throws IOException synchronized int read() throws IOException
{ {
if(stream == null) if(stream == null)
{ throw new IOException("Invalid FileDescriptor");
throw new IOException();
}
try try
{ {
if(false) throw new system.io.IOException(); if(false) throw new system.io.IOException();
return stream.Read(buf, offset, length); return stream.ReadByte();
} }
catch(system.io.IOException x) catch(system.io.IOException x)
{ {
@ -240,16 +288,29 @@ public final class FileDescriptor
// TODO map al the other exceptions as well... // TODO map al the other exceptions as well...
} }
synchronized void write(byte[] buf, int offset, int length) throws IOException synchronized int read(byte[] buf, int offset, int len) throws IOException
{ {
if(stream == null) if(stream == null)
{ throw new IOException("Invalid FileDescriptor");
throw new IOException();
} if (len == 0)
return(0);
if ((offset < 0) || (offset > buf.length))
throw new IllegalArgumentException("Offset invalid: " + offset);
if ((len < 0) || (len > (buf.length - offset)))
throw new IllegalArgumentException("Length invalid: " + len);
try try
{ {
if(false) throw new system.io.IOException(); if(false) throw new system.io.IOException();
stream.Write(buf, offset, length); int count = stream.Read(buf, offset, len);
if(count == 0)
{
count = -1;
}
return count;
} }
catch(system.io.IOException x) catch(system.io.IOException x)
{ {
@ -258,19 +319,16 @@ public final class FileDescriptor
// TODO map al the other exceptions as well... // TODO map al the other exceptions as well...
} }
synchronized long skip(long n) throws IOException synchronized void write(int b) throws IOException
{ {
if(stream == null) if(stream == null)
{ {
throw new IOException(); throw new IOException("Invalid FileDescriptor");
} }
try try
{ {
if(false) throw new system.io.IOException(); if(false) throw new system.io.IOException();
// TODO this is broken, because non-seekable streams should support skip as well... stream.WriteByte((byte)b);
// (and I don't think we should seek past EOF here)
stream.Seek(n, SeekOrigin.Current);
return n;
} }
catch(system.io.IOException x) catch(system.io.IOException x)
{ {
@ -278,4 +336,45 @@ public final class FileDescriptor
} }
// TODO map al the other exceptions as well... // TODO map al the other exceptions as well...
} }
}
synchronized void write(byte[] buf, int offset, int len) throws IOException
{
if(stream == null)
throw new IOException("Invalid FileDescriptor");
if (len == 0)
return;
if ((offset < 0) || (offset > buf.length))
throw new IllegalArgumentException("Offset invalid: " + offset);
if ((len < 0) || (len > (buf.length - offset)))
throw new IllegalArgumentException("Length invalid: " + len);
try
{
if(false) throw new system.io.IOException();
stream.Write(buf, offset, len);
}
catch(system.io.IOException x)
{
throw new IOException(x.get_Message());
}
// TODO map al the other exceptions as well...
}
synchronized int available() throws IOException
{
if(stream == null)
throw new IOException("Invalid FileDescriptor");
// TODO might need to implement this
return 0;
}
long getNativeFd()
{
throw new Error("getNativeFd not supported");
}
} // class FileDescriptor

Просмотреть файл

@ -1,396 +0,0 @@
/* FileInputStream.java -- An input stream that reads from disk files.
Copyright (C) 1998 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.io;
import gnu.classpath.Configuration;
import java.nio.channels.FileChannel;
import gnu.java.nio.FileChannelImpl;
/**
* This class is a stream that reads its bytes from a file.
*
* @version 0.0
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public class FileInputStream extends InputStream
{
/*************************************************************************/
/*
* Class Variables and Initializers
*/
static
{
if (Configuration.INIT_LOAD_LIBRARY)
{
System.loadLibrary ("javaio");
}
}
/*************************************************************************/
/*
* Instance Variables
*/
/**
* This is the native file handle for the file this stream is reading from
*/
private FileDescriptor fd;
/*************************************************************************/
/*
* Constructors
*/
/**
* This method initializes a <code>FileInputStream</code> to read from the
* specified named file. A security check is first made to determine
* whether or not access to this file is allowed. This is done by
* calling the <code>checkRead()</code> method of the <code>SecurityManager</code>
* (if one exists) with the name of this file. An exception is thrown
* if reading is not allowed. If the file does not exist, an exception
* is also thrown.
*
* @param name The name of the file this stream should read from
*
* @exception SecurityException If read access to the file is not allowed
* @exception FileNotFoundException If the file does not exist.
*/
public
FileInputStream(String name) throws SecurityException, FileNotFoundException
{
this(new File(name));
}
/*************************************************************************/
/**
* This method initializes a <code>FileInputStream</code> to read from the
* specified <code>File</code> object. A security check is first made to determine
* whether or not access to this file is allowed. This is done by
* calling the <code>checkRead()</code> method of the <code>SecurityManager</code>
* (if one exists) with the name of this file. An exception is thrown
* if reading is not allowed. If the file does not exist, an exception
* is also thrown.
*
* @param file The <code>File</code> object this stream should read from
*
* @exception SecurityException If read access to the file is not allowed
* @exception FileNotFoundException If the file does not exist.
*/
public
FileInputStream(File file) throws SecurityException, FileNotFoundException
{
// Talk about the lazy man's way out. The File.exists() method does
// a security check so don't repeat it here.
if (!file.exists())
throw new FileNotFoundException(file.getName());
fd = FileDescriptor.open(file.getPath(), FileDescriptor.Read);
}
/*************************************************************************/
/**
* This method initializes a <code>FileInputStream</code> to read from the
* specified <code>FileDescriptor</code> object. A security check is first made to
* determine whether or not access to this file is allowed. This is done by
* calling the <code>checkRead()</code> method of the <code>SecurityManager</code>
* (if one exists) with the specified <code>FileDescriptor</code> An exception is
* thrown if reading is not allowed.
*
* @param fd The <code>FileDescriptor</code> object this stream should read from
*
* @exception SecurityException If read access to the file is not allowed
*/
public
FileInputStream(FileDescriptor fd) throws SecurityException
{
// Hmmm, no other exception but this one to throw, but if the descriptor
// isn't valid, we surely don't have "permission" to read from it.
if (!fd.valid())
throw new SecurityException("Invalid FileDescriptor");
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkRead(fd);
this.fd = fd;
}
/*************************************************************************/
/*
* Instance Methods
*/
/**
* This method returns a <code>FileDescriptor</code> object representing the
* underlying native file handle of the file this stream is reading
* from
*
* @return A <code>FileDescriptor</code> for this stream
*
* @exception IOException If an error occurs
*/
public final FileDescriptor
getFD() throws IOException
{
return fd;
}
/*************************************************************************/
/**
* This method returns the number of bytes that can be read from this
* stream before a read can block. A return of 0 indicates that blocking
* might (or might not) occur on the very next read attempt.
* <p>
* This method returns the number of unread bytes remaining in the file if
* the descriptor being read from is an actual file. If this method is
* reading from a ''special'' file such a the standard input, this method
* will return the appropriate value for the stream being read.
* <p>
* Be aware that reads on plain files that do not reside locally might
* possibly block even if this method says they should not. For example,
* a remote server might crash, preventing an NFS mounted file from being
* read.
*
* @return The number of bytes that can be read before blocking could occur
*
* @exception IOException If an error occurs
*/
public int
available() throws IOException
{
int retval = (int)(fd.getLength() - fd.getFilePointer());
if (retval <= 0)
return(0);
return(retval);
}
/*************************************************************************/
/**
* This method skips the specified number of bytes in the stream. It
* returns the actual number of bytes skipped, which may be less than the
* requested amount.
* <p>
* This method reads and discards bytes into a 256 byte array until the
* specified number of bytes were skipped or until either the end of stream
* is reached or a read attempt returns a short count. Subclasses can
* override this metho to provide a more efficient implementation where
* one exists.
*
* @param num_bytes The requested number of bytes to skip
*
* @return The actual number of bytes skipped.
*
* @exception IOException If an error occurs
*/
public long
skip(long num_bytes) throws IOException
{
if (num_bytes <= 0)
return(0);
if (num_bytes > available())
num_bytes = available();
long bytes_skipped = fd.skip(num_bytes);
return(bytes_skipped);
}
/*************************************************************************/
/**
* This method reads an unsigned byte from the input stream and returns it
* as an int in the range of 0-255. This method also will return -1 if
* the end of the stream has been reached.
* <p>
* This method will block until the byte can be read.
*
* @return The byte read or -1 if end of stream
*
* @exception IOException If an error occurs
*/
public int
read() throws IOException
{
byte[] buf = new byte[1];
int bytes_read = fd.read(buf, 0, buf.length);
if (bytes_read == 0)
return(-1);
if (bytes_read == -1)
return(-1);
return((buf[0] & 0xFF));
}
/*************************************************************************/
/**
* This method reads bytes from a stream and stores them into a caller
* supplied buffer. This method attempts to completely fill the buffer,
* but can return before doing so. The actual number of bytes read is
* returned as an int. A -1 is returned to indicate the end of the stream.
* <p>
* This method will block until some data can be read.
* <p>
* This method operates by calling an overloaded read method like so:
* <code>read(buf, 0, buf.length)</code>
*
* @param buf The buffer into which the bytes read will be stored.
*
* @return The number of bytes read or -1 if end of stream.
*
* @exception IOException If an error occurs.
*/
public int
read(byte[] buf) throws IOException
{
return(read(buf, 0, buf.length));
}
/*************************************************************************/
/**
* This method read bytes from a stream and stores them into a caller
* supplied buffer. It starts storing the data at index <code>offset</code> into
* the buffer and attempts to read <code>len</code> bytes. This method can
* return before reading the number of bytes requested. The actual number
* of bytes read is returned as an int. A -1 is returned to indicate the
* end of the stream.
* <p>
* This method will block until some data can be read.
*
* @param buf The array into which the bytes read should be stored
* @param offset The offset into the array to start storing bytes
* @param len The requested number of bytes to read
*
* @return The actual number of bytes read, or -1 if end of stream.
*
* @exception IOException If an error occurs.
*/
public int
read(byte[] buf, int offset, int len) throws IOException
{
if (len == 0)
return(0);
int bytes_read = fd.read(buf, offset, len);
if (bytes_read == 0)
return(-1);
if (bytes_read == -1)
return(-1);
return(bytes_read);
}
/*************************************************************************/
/**
* This method closes the stream. Any futher attempts to read from the
* stream will likely generate an IOException since the underlying file
* will be closed.
*
* @exception IOException If an error occurs.
*/
public void
close() throws IOException
{
fd.close();
}
/*************************************************************************/
/**
* This method ensures that the underlying file is closed when this object
* is garbage collected. Since there is a system dependent limit on how
* many files a single process can have open, it is a good idea to close
* streams when they are no longer needed rather than waiting for garbage
* collectio to automatically close them.
*
* @exception IOException If an error occurs
*/
protected void
finalize() throws IOException
{
if(fd != null)
{
close();
}
}
/*************************************************************************/
/**
* This method creates a java.nio.channels.FileChannel.
* Nio does not allow one to create a file channel directly.
* A file channel must be created by first creating an instance of
* Input/Output/RandomAccessFile and invoking the getChannel() method on it.
*/
private FileChannel ch; /* cached associated file-channel */
public FileChannel
getChannel()
{
synchronized (this)
{
// if (ch == null)
// ch = new gnu.java.nio.FileChannelImpl(native_fd,
// this);
}
return ch;
}
} // class FileInputStream

Просмотреть файл

@ -1,339 +0,0 @@
/* FileOutputStream.java -- Writes to a file on disk.
Copyright (C) 1998, 2001 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.io;
import gnu.classpath.Configuration;
import java.nio.channels.FileChannel;
import gnu.java.nio.FileChannelImpl;
/**
* This classes allows a stream of data to be written to a disk file or
* any open <code>FileDescriptor</code>.
*
* @version 0.0
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public class FileOutputStream extends OutputStream
{
/*************************************************************************/
/*
* Class Variables and Initializers
*/
static
{
if (Configuration.INIT_LOAD_LIBRARY)
{
System.loadLibrary ("javaio");
}
}
/*************************************************************************/
/*
* Instance Variables
*/
/**
* This is the native file handle
*/
private FileDescriptor fd;
/*************************************************************************/
/*
* Constructors
*/
/**
* This method initializes a <code>FileOutputStream</code> object to write
* to the named file. The file is created if it does not exist, and
* the bytes written are written starting at the beginning of the file.
* <p>
* Before opening a file, a security check is performed by calling the
* <code>checkWrite</code> method of the <code>SecurityManager</code> (if
* one exists) with the name of the file to be opened. An exception is
* thrown if writing is not allowed.
*
* @param name The name of the file this stream should write to
*
* @exception SecurityException If write access to the file is not allowed
* @exception IOException If a non-security error occurs
*/
public
FileOutputStream(String name) throws SecurityException, IOException
{
this(name, false);
}
/*************************************************************************/
/**
* This method initializes a <code>FileOutputStream</code> object to write
* to the specified <code>File</code> object. The file is created if it
* does not exist, and the bytes written are written starting at the
* beginning of the file.
* <p>
* Before opening a file, a security check is performed by calling the
* <code>checkWrite</code> method of the <code>SecurityManager</code> (if
* one exists) with the name of the file to be opened. An exception is
* thrown if writing is not allowed.
*
* @param file The <code>File</code> object this stream should write to
*
* @exception SecurityException If write access to the file is not allowed
* @exception IOException If a non-security error occurs
*/
public
FileOutputStream(File file) throws SecurityException, IOException
{
this(file.getPath(), false);
}
/*************************************************************************/
/**
* This method initializes a <code>FileOutputStream</code> object to write
* to the named file. The file is created if it does not exist, and
* the bytes written are written starting at the beginning of the file if
* the <code>append</code> argument is <code>false</code> or at the end
* of the file if the <code>append</code> argument is true.
* <p>
* Before opening a file, a security check is performed by calling the
* <code>checkWrite</code> method of the <code>SecurityManager</code> (if
* one exists) with the name of the file to be opened. An exception is
* thrown if writing is not allowed.
*
* @param name The name of the file this stream should write to
* @param append <code>true</code> to append bytes to the end of the file, or <code>false</code> to write bytes to the beginning
*
* @exception SecurityException If write access to the file is not allowed
* @exception IOException If a non-security error occurs
*/
public
FileOutputStream(String name, boolean append) throws SecurityException,
IOException
{
SecurityManager sm = System.getSecurityManager();
if (sm != null)
{
// try
// {
sm.checkWrite(name);
// }
// catch(AccessControlException e)
// {
// throw new SecurityException(e.getMessage());
// }
}
fd = FileDescriptor.open((new File(name)).getAbsolutePath(), append ? FileDescriptor.Append : FileDescriptor.Write);
}
/*************************************************************************/
/**
* This method initializes a <code>FileOutputStream</code> object to write
* to the file represented by the specified <code>FileDescriptor</code>
* object. This method does not create any underlying disk file or
* reposition the file pointer of the given descriptor. It assumes that
* this descriptor is ready for writing as is.
* <p>
* Before opening a file, a security check is performed by calling the
* <code>checkWrite</code> method of the <code>SecurityManager</code> (if
* one exists) with the specified <code>FileDescriptor</code> as an argument.
* An exception is thrown if writing is not allowed.
*
* @param file The <code>FileDescriptor</code> this stream should write to
*
* @exception SecurityException If write access to the file is not allowed
*/
public
FileOutputStream(FileDescriptor fd) throws SecurityException
{
// Hmm, no other exception but this one to throw, but if the descriptor
// isn't valid, we surely don't have "permission" to write to it.
if (!fd.valid())
throw new SecurityException("Invalid FileDescriptor");
SecurityManager sm = System.getSecurityManager();
if (sm != null)
{
// try
// {
// sm.checkWrite(fd);
// }
// catch(AccessControlException e)
// {
// throw new SecurityException(e.getMessage());
// }
}
this.fd = fd;
}
/*************************************************************************/
/**
* This method returns a <code>FileDescriptor</code> object representing
* the file that is currently being written to
*
* @return A <code>FileDescriptor</code> object for this stream
*
* @exception IOException If an error occurs
*/
public final FileDescriptor
getFD() throws IOException
{
return fd;
}
/*************************************************************************/
/**
* This method writes a single byte of data to the file.
*
* @param b The byte of data to write, passed as an <code>int</code>
*
* @exception IOException If an error occurs
*/
public void
write(int b) throws IOException
{
byte[] buf = new byte[1];
buf[0] = (byte)(b & 0xFF);
fd.write(buf, 0, buf.length);
}
/*************************************************************************/
/**
* This method writes all the bytes in the specified array to the
* file.
*
* @param buf The array of bytes to write to the file
*
* @exception IOException If an error occurs
*/
public void
write(byte[] buf) throws IOException
{
fd.write(buf, 0, buf.length);
}
/*************************************************************************/
/**
* This method writes <code>len</code> bytes from the byte array
* <code>buf</code> to the file starting at index <code>offset</code>.
*
* @param buf The array of bytes to write to the file
* @param offset The offset into the array to start writing bytes from
* @param len The number of bytes to write to the file
*
* @exception IOException If an error occurs
*/
public void
write(byte[] buf, int offset, int len) throws IOException
{
fd.write(buf, offset, len);
}
/*************************************************************************/
/**
* This method closes the underlying file. Any further attempts to
* write to this stream will likely generate an exception since the
* file is closed.
*
* @exception IOException If an error occurs
*/
public void
close() throws IOException
{
fd.close();
}
/*************************************************************************/
/**
* This method closes the stream when this object is being garbage
* collected.
*
* @exception IOException If an error occurs (ignored by the Java runtime)
*/
protected void
finalize() throws IOException
{
if(fd != null)
{
close();
}
}
/*************************************************************************/
/**
* This method creates a java.nio.channels.FileChannel.
* Nio does not allow one to create a file channel directly.
* A file channel must be created by first creating an instance of
* Input/Output/RandomAccessFile and invoking the getChannel() method on it.
*/
private FileChannel ch; /* cached associated file-channel */
public FileChannel
getChannel()
{
synchronized (this)
{
// if (ch == null)
// ch = new gnu.java.nio.FileChannelImpl(native_fd,
// this);
}
return ch;
}
} // class FileOutputStream

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,364 @@
/* StringHelper.java -- helper class adapted from java/lang/String.java
Copyright (C) 1998, 1999, 2000, 2001, 2002 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.lang;
import java.util.Locale;
import java.io.UnsupportedEncodingException;
import java.io.CharConversionException;
import gnu.java.io.EncodingManager;
import gnu.java.lang.CharData;
public final class StringHelper
{
private StringHelper() {}
public static boolean equalsIgnoreCase(String s1, String s2)
{
int len = s1.length();
if(s2 == null || len != s2.length())
{
return false;
}
for(int i = 0; i < len; i++)
{
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
if(c1 != c2 && (Character.toUpperCase(c1) != Character.toUpperCase(c2)) &&
(Character.toLowerCase(c1) != Character.toLowerCase(c2)))
{
return false;
}
}
return true;
}
public static int compareTo(String s1, String s2)
{
int len = Math.min(s1.length(), s2.length());
for(int i = 0; i < len; i++)
{
int diff = s1.charAt(i) - s2.charAt(i);
if(diff != 0)
{
return diff;
}
}
return s1.length() - s2.length();
}
public static int compareToIgnoreCase(String s1, String s2)
{
int len = Math.min(s1.length(), s2.length());
for(int i = 0; i < len; i++)
{
int result = Character.toLowerCase(Character.toUpperCase(s1.charAt(i)))
- Character.toLowerCase(Character.toUpperCase(s2.charAt(i)));
if (result != 0)
return result;
}
return s1.length() - s2.length();
}
public static String toLowerCase(String s)
{
return toLowerCase(s, Locale.getDefault());
}
public static String toLowerCase(String s, Locale loc)
{
// First, see if the current string is already lower case.
boolean turkish = "tr".equals(loc.getLanguage());
int len = s.length();
for(int i = 0; i < len; i++)
{
char ch = s.charAt(i);
if((turkish && ch == '\u0049') || ch != Character.toLowerCase(ch))
{
// Now we perform the conversion. Fortunately, there are no multi-character
// lowercase expansions in Unicode 3.0.0.
char[] newStr = (char[])s.toCharArray();
for(; i < len; i++)
{
ch = newStr[i];
// Hardcoded special case.
newStr[i] = (turkish && ch == '\u0049') ? '\u0131' : Character.toLowerCase(ch);
}
return new String(newStr);
}
}
return s;
}
public static String toUpperCase(String s)
{
return toUpperCase(s, Locale.getDefault());
}
public static String toUpperCase(String s, Locale loc)
{
// First, see how many characters we have to grow by, as well as if the
// current string is already upper case.
boolean turkish = "tr".equals(loc.getLanguage());
int expand = 0;
boolean unchanged = true;
int i = s.length();
int x = i;
while (--i >= 0)
{
char ch = s.charAt(--x);
expand += upperCaseExpansion(ch);
unchanged = (unchanged && expand == 0
&& ! (turkish && ch == '\u0069')
&& ch == Character.toUpperCase(ch));
}
if (unchanged)
return s;
// Now we perform the conversion.
i = s.length();
if (expand == 0)
{
char[] newStr = s.toCharArray();
while (--i >= 0)
{
char ch = s.charAt(x);
// Hardcoded special case.
newStr[x++] = (turkish && ch == '\u0069') ? '\u0130'
: Character.toUpperCase(ch);
}
return new String(newStr);
}
// Expansion is necessary.
char[] newStr = new char[s.length() + expand];
int j = 0;
while (--i >= 0)
{
char ch = s.charAt(x++);
// Hardcoded special case.
if (turkish && ch == '\u0069')
{
newStr[j++] = '\u0130';
continue;
}
expand = upperCaseExpansion(ch);
if (expand > 0)
{
int index = upperCaseIndex(ch);
while (expand-- >= 0)
newStr[j++] = upperExpand[index++];
}
else
newStr[j++] = Character.toUpperCase(ch);
}
return new String(newStr);
}
private static int upperCaseExpansion(char ch)
{
return Character.direction[Character.readChar(ch) >> 7] & 3;
}
private static int upperCaseIndex(char ch)
{
// Simple binary search for the correct character.
int low = 0;
int hi = upperSpecial.length - 2;
int mid = ((low + hi) >> 2) << 1;
char c = upperSpecial[mid];
while (ch != c)
{
if (ch < c)
hi = mid - 2;
else
low = mid + 2;
mid = ((low + hi) >> 2) << 1;
c = upperSpecial[mid];
}
return upperSpecial[mid + 1];
}
private static final char[] upperExpand = CharData.UPPER_EXPAND.toCharArray();
private static final char[] upperSpecial = CharData.UPPER_SPECIAL.toCharArray();
public static String NewString(byte[] ascii, int hibyte, int offset, int count)
{
if (offset < 0 || count < 0 || offset + count > ascii.length)
throw new StringIndexOutOfBoundsException();
char[] value = new char[count];
hibyte <<= 8;
offset += count;
while (--count >= 0)
value[count] = (char) (hibyte | (ascii[--offset] & 0xff));
return new String(value);
}
public static String NewString(byte[] ascii, int hibyte)
{
return NewString(ascii, hibyte, 0, ascii.length);
}
public static String NewString(byte[] data, int offset, int count, String encoding)
throws UnsupportedEncodingException
{
if (offset < 0 || count < 0 || offset + count > data.length)
throw new StringIndexOutOfBoundsException();
try
{
// XXX Consider using java.nio here.
return new String(EncodingManager.getDecoder(encoding)
.convertToChars(data, offset, count));
}
catch (CharConversionException cce)
{
throw new Error(cce);
}
}
public static String NewString(byte[] data, String encoding)
throws UnsupportedEncodingException
{
return NewString(data, 0, data.length, encoding);
}
public static String NewString(byte[] data, int offset, int count)
{
if (offset < 0 || count < 0 || offset + count > data.length)
throw new StringIndexOutOfBoundsException();
try
{
// XXX Consider using java.nio here.
return new String(EncodingManager.getDecoder()
.convertToChars(data, offset, count));
}
catch (CharConversionException cce)
{
throw new Error(cce);
}
}
public static String NewString(byte[] data)
{
return NewString(data, 0, data.length);
}
public static String NewString(char[] data, int offset, int count, boolean dont_copy)
{
return new String(data, offset, count);
}
public static void getBytes(String s, int srcBegin, int srcEnd, byte dst[], int dstBegin)
{
if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > s.length())
throw new StringIndexOutOfBoundsException();
int i = srcEnd - srcBegin;
while (--i >= 0)
dst[dstBegin++] = (byte)s.charAt(srcBegin++);
}
public static byte[] getBytes(String s, String enc) throws UnsupportedEncodingException
{
try
{
// XXX Consider using java.nio here.
return EncodingManager.getEncoder(enc)
.convertToBytes(s.toCharArray());
}
catch (CharConversionException e)
{
return null;
}
}
public static byte[] getBytes(String s)
{
try
{
// XXX Consider using java.nio here.
return EncodingManager.getEncoder()
.convertToBytes(s.toCharArray());
}
catch (CharConversionException e)
{
return null;
}
}
public static boolean regionMatches(String s, int toffset, String other, int ooffset, int len)
{
return regionMatches(s, false, toffset, other, ooffset, len);
}
public static boolean regionMatches(String s, boolean ignoreCase, int toffset,
String other, int ooffset, int len)
{
if (toffset < 0 || ooffset < 0 || toffset + len > s.length()
|| ooffset + len > other.length())
return false;
while (--len >= 0)
{
char c1 = s.charAt(toffset++);
char c2 = other.charAt(ooffset++);
// Note that checking c1 != c2 is redundant when ignoreCase is true,
// but it avoids method calls.
if (c1 != c2
&& (! ignoreCase
|| (Character.toLowerCase(c1) != Character.toLowerCase(c2)
&& (Character.toUpperCase(c1)
!= Character.toUpperCase(c2)))))
return false;
}
return true;
}
public static String trim(String s)
{
int limit = s.length();
if (limit == 0 || (s.charAt(0) > '\u0020'
&& s.charAt(limit - 1) > '\u0020'))
return s;
int begin = 0;
do
if (begin == limit)
return "";
while (s.charAt(begin++) <= '\u0020');
int end = limit;
while (s.charAt(--end) <= '\u0020');
return s.substring(begin - 1, end + 1);
}
}

Просмотреть файл

@ -118,12 +118,7 @@ final class VMClassLoader
*/ */
static Class loadClass(String name, boolean resolve) throws ClassNotFoundException static Class loadClass(String name, boolean resolve) throws ClassNotFoundException
{ {
Class c = Class.loadBootstrapClass(name, false); return Class.loadBootstrapClass(name, false);
if(c == null)
{
throw new ClassNotFoundException(name);
}
return c;
} }
/** /**

Просмотреть файл

@ -134,19 +134,27 @@ public final class Field extends AccessibleObject implements Member
/** /**
* Compare two objects to see if they are semantically equivalent. * Compare two objects to see if they are semantically equivalent.
* Two Fields are semantically equivalent if they have the same declaring * Two Fields are semantically equivalent if they have the same declaring
* class, name, and type. Since you can't creat a Field except through * class, name, and type.
* the VM, this is just the == relation.
* *
* @param o the object to compare to * @param o the object to compare to
* @return <code>true</code> if they are equal; <code>false</code> if not * @return <code>true</code> if they are equal; <code>false</code> if not
*/ */
public boolean equals(Object o) public boolean equals(Object o)
{ {
if(o instanceof Field) if(!(o instanceof Field))
{ return false;
return fieldCookie == ((Field)o).fieldCookie;
} Field f = (Field)o;
return false; if(!getName().equals(f.getName()))
return false;
if(declaringClass != f.declaringClass)
return false;
if(getType() != f.getType())
return false;
return true;
} }
/** /**

Просмотреть файл

@ -175,27 +175,6 @@ public final class Method extends AccessibleObject implements Member
*/ */
public boolean equals(Object o) public boolean equals(Object o)
{ {
// Implementation note:
// The following is a correct but possibly slow implementation.
//
// This class has a private field 'slot' that could be used by
// the VM implementation to "link" a particular method to a Class.
// In that case equals could be simply implemented as:
//
// if (o instanceof Method)
// {
// Method m = (Method)o;
// return m.declaringClass == this.declaringClass
// && m.slot == this.slot;
// }
// return false;
//
// If a VM uses the Method class as their native/internal representation
// then just using the following would be optimal:
//
// return return this == o;
//
if (!(o instanceof Method)) if (!(o instanceof Method))
return false; return false;
@ -206,6 +185,9 @@ public final class Method extends AccessibleObject implements Member
if(declaringClass != m.declaringClass) if(declaringClass != m.declaringClass)
return false; return false;
if(getReturnType() != m.getReturnType())
return false;
Class[] params1 = getParameterTypes(); Class[] params1 = getParameterTypes();
Class[] params2 = m.getParameterTypes(); Class[] params2 = m.getParameterTypes();
if(params1.length != params2.length) if(params1.length != params2.length)

Просмотреть файл

@ -146,15 +146,15 @@ public class Starter
{ {
if(args[i][0] == '-') if(args[i][0] == '-')
{ {
if(args[i] == "-help") if(args[i] == "-help" || args[i] == "-?")
{ {
break; break;
} }
else if(args[i] == "-save") else if(args[i] == "-Xsave")
{ {
saveAssembly = true; saveAssembly = true;
} }
else if(args[i] == "-time") else if(args[i] == "-Xtime")
{ {
new Timer(); new Timer();
} }
@ -179,6 +179,10 @@ public class Starter
{ {
java.lang.System.setProperty("ikvm.boot.class.path", args[i].Substring(16)); java.lang.System.setProperty("ikvm.boot.class.path", args[i].Substring(16));
} }
else if(args[i] == "-Xlogclf")
{
JVM.LogClassLoadFailures = true;
}
else else
{ {
Console.Error.WriteLine("{0}: illegal argument", args[i]); Console.Error.WriteLine("{0}: illegal argument", args[i]);
@ -201,14 +205,15 @@ public class Starter
Console.Error.WriteLine(" (to execute a jar file)"); Console.Error.WriteLine(" (to execute a jar file)");
Console.Error.WriteLine(); Console.Error.WriteLine();
Console.Error.WriteLine("where options include:"); Console.Error.WriteLine("where options include:");
Console.Error.WriteLine(" -help display this message"); Console.Error.WriteLine(" -? -help display this message");
Console.Error.WriteLine(" -cp -classpath <directories and zip/jar files separated by ;>"); Console.Error.WriteLine(" -cp -classpath <directories and zip/jar files separated by {0}>", Path.PathSeparator);
Console.Error.WriteLine(" set search path for application classes and resources"); Console.Error.WriteLine(" set search path for application classes and resources");
Console.Error.WriteLine(" -save save the generated assembly (for debugging)");
Console.Error.WriteLine(" -time time the execution");
Console.Error.WriteLine(" -D<name>=<value> set a system property"); Console.Error.WriteLine(" -D<name>=<value> set a system property");
Console.Error.WriteLine(" -Xbootclasspath:<directories and zip/jar files separated by ;>"); Console.Error.WriteLine(" -Xsave save the generated assembly (for debugging)");
Console.Error.WriteLine(" -Xtime time the execution");
Console.Error.WriteLine(" -Xbootclasspath:<directories and zip/jar files separated by {0}>", Path.PathSeparator);
Console.Error.WriteLine(" set search path for bootstrap classes and resources"); Console.Error.WriteLine(" set search path for bootstrap classes and resources");
Console.Error.WriteLine(" -Xlogclf log class load failures");
return 1; return 1;
} }
try try