зеркало из https://github.com/mono/ikvm-fork.git
*** empty log message ***
This commit is contained in:
Родитель
b4b73ec1c4
Коммит
66d7c812b3
|
@ -627,10 +627,13 @@ class ClassFile
|
|||
{
|
||||
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
|
||||
if(JVM.LogClassLoadFailures)
|
||||
{
|
||||
Console.Error.WriteLine(x);
|
||||
}
|
||||
return new UnloadableTypeWrapper(name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ class ClassLoaderWrapper
|
|||
internal void LoadRemappedTypes()
|
||||
{
|
||||
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);
|
||||
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);
|
||||
|
@ -152,6 +152,11 @@ class ClassLoaderWrapper
|
|||
types.Add(name, tw);
|
||||
typeToTypeWrapper.Add(tw.Type, tw);
|
||||
}
|
||||
}
|
||||
|
||||
internal void LoadRemappedTypesStep2()
|
||||
{
|
||||
MapXml.Root map = MapXmlGenerator.Generate();
|
||||
foreach(MapXml.Class c in map.remappings)
|
||||
{
|
||||
((RemappedTypeWrapper)types[c.Name]).LoadRemappings(c);
|
||||
|
@ -175,8 +180,18 @@ class ClassLoaderWrapper
|
|||
return LoadClassByDottedName(name.Replace('/', '.'));
|
||||
}
|
||||
|
||||
// TODO implement vmspec 5.3.4 Loading Constraints
|
||||
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)
|
||||
{
|
||||
|
@ -222,8 +237,7 @@ class ClassLoaderWrapper
|
|||
case 'Z':
|
||||
return GetBootstrapClassLoader().CreateArrayType(name, typeof(bool), dims);
|
||||
default:
|
||||
// TODO I'm not sure this is the right exception here (instead we could throw a NoClassDefFoundError)
|
||||
throw JavaException.ClassNotFoundException(name);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if(this == GetBootstrapClassLoader())
|
||||
|
@ -247,7 +261,7 @@ class ClassLoaderWrapper
|
|||
}
|
||||
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
|
||||
|
@ -755,6 +769,7 @@ class ClassLoaderWrapper
|
|||
{
|
||||
bootstrapClassLoader = new ClassLoaderWrapper(null);
|
||||
bootstrapClassLoader.LoadRemappedTypes();
|
||||
bootstrapClassLoader.LoadRemappedTypesStep2();
|
||||
}
|
||||
return bootstrapClassLoader;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,8 @@ sealed class JavaException
|
|||
|
||||
private class BootstrapClassMissing : Exception {}
|
||||
|
||||
private static ConstructorInfo classNotFoundConstructor;
|
||||
|
||||
internal static Exception ClassNotFoundException(string s, params object[] args)
|
||||
{
|
||||
// HACK if java.lang.ClassNotFoundException is not found, this method would recurse until the
|
||||
|
@ -86,8 +88,11 @@ sealed class JavaException
|
|||
classNotFound = true;
|
||||
//Console.WriteLine("ClassNotFoundException: " + s);
|
||||
s = String.Format(s, args);
|
||||
ConstructorInfo ci = ClassLoaderWrapper.GetType("java.lang.ClassNotFoundException").GetConstructor(new Type[] { typeof(string) });
|
||||
return (Exception)ci.Invoke(new object[] { s });
|
||||
if(classNotFoundConstructor == null)
|
||||
{
|
||||
classNotFoundConstructor = ClassLoaderWrapper.GetType("java.lang.ClassNotFoundException").GetConstructor(new Type[] { typeof(string) });
|
||||
}
|
||||
return (Exception)classNotFoundConstructor.Invoke(new object[] { s });
|
||||
}
|
||||
catch(BootstrapClassMissing)
|
||||
{
|
||||
|
|
|
@ -27,100 +27,6 @@ using System.Reflection;
|
|||
|
||||
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)
|
||||
{
|
||||
return b ? "true" : "false";
|
||||
|
@ -216,91 +122,12 @@ public class StringHelper
|
|||
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)
|
||||
{
|
||||
// TODO
|
||||
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
|
||||
// has to be much more complex
|
||||
public static int hashCode(object s)
|
||||
|
@ -313,18 +140,6 @@ public class StringHelper
|
|||
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)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -829,27 +829,27 @@ class UnloadableTypeWrapper : TypeWrapper
|
|||
|
||||
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)
|
||||
{
|
||||
throw new InvalidOperationException("GetMethodImpl called on UnloadableTypeWrapper");
|
||||
throw new InvalidOperationException("GetMethodImpl called on UnloadableTypeWrapper: " + Name);
|
||||
}
|
||||
|
||||
public override Type Type
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new InvalidOperationException("get_Type called on UnloadableTypeWrapper");
|
||||
}
|
||||
}
|
||||
throw new InvalidOperationException("get_Type called on UnloadableTypeWrapper: " + Name);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsInterface
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
throw new InvalidOperationException("get_DeclaringTypeWrapper called on UnloadableTypeWrapper");
|
||||
throw new InvalidOperationException("get_DeclaringTypeWrapper called on UnloadableTypeWrapper: " + Name);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
mb.SetImplementationFlags(method.GetMethodImplementationFlags() | MethodImplAttributes.Synchronized);
|
||||
|
@ -1963,8 +1963,9 @@ class DynamicTypeWrapper : TypeWrapper
|
|||
if(retTypeWrapper.IsUnloadable)
|
||||
{
|
||||
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...
|
||||
((MethodBuilder)method).DefineParameter(0, ParameterAttributes.None, null).SetCustomAttribute(attrib);
|
||||
// NOTE since DefineParameter(0, ...) throws an exception (bug in .NET, I believe),
|
||||
// we attach the attribute to the method instead of the return value
|
||||
((MethodBuilder)method).SetCustomAttribute(attrib);
|
||||
}
|
||||
for(int i = 0; i < argTypeWrappers.Length; i++)
|
||||
{
|
||||
|
@ -2150,12 +2151,27 @@ class RemappedTypeWrapper : TypeWrapper
|
|||
{
|
||||
binding |= BindingFlags.Instance;
|
||||
}
|
||||
Type t = this.type;
|
||||
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)
|
||||
{
|
||||
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 temp = MethodWrapper.Create(this, md, overrideMethod, redirect, modifiers);
|
||||
newopc = temp.EmitNewobj;
|
||||
invokespecial = temp.EmitCall;
|
||||
invokevirtual = temp.EmitCallvirt;
|
||||
MethodWrapper.CreateEmitters(overrideMethod, redirect, ref invokespecial, ref invokevirtual, ref newopc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2234,6 +2246,14 @@ class RemappedTypeWrapper : TypeWrapper
|
|||
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);
|
||||
mw.EmitNewobj = newopc;
|
||||
mw.EmitCall = invokespecial;
|
||||
|
@ -2312,19 +2332,42 @@ class RemappedTypeWrapper : TypeWrapper
|
|||
{
|
||||
binding |= BindingFlags.Instance;
|
||||
}
|
||||
Type t = this.type;
|
||||
MethodBase redirect = null;
|
||||
if(constructor.redirect.Class != null)
|
||||
{
|
||||
t = Type.GetType(constructor.redirect.Class, true);
|
||||
}
|
||||
MethodBase redirect = null;
|
||||
if(constructor.redirect.Name != null)
|
||||
{
|
||||
redirect = t.GetMethod(constructor.redirect.Name, binding, null, CallingConventions.Standard, redir.ArgTypes, null);
|
||||
TypeWrapper tw = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(constructor.redirect.Class);
|
||||
if(tw is DynamicTypeWrapper)
|
||||
{
|
||||
MethodDescriptor md1 = new MethodDescriptor(GetClassLoader(), constructor.redirect.Name != null ? constructor.redirect.Name : "<init>", sig);
|
||||
MethodWrapper mw1 = tw.GetMethodWrapper(md1, false);
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -2410,10 +2453,14 @@ class RemappedTypeWrapper : TypeWrapper
|
|||
{
|
||||
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);
|
||||
fw.EmitGet = CodeEmitter.Create(OpCodes.Call, method);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -3525,33 +3572,38 @@ sealed class MethodWrapper
|
|||
throw new InvalidOperationException();
|
||||
}
|
||||
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)
|
||||
{
|
||||
wrapper.EmitCall = CodeEmitter.Create(OpCodes.Call, (ConstructorInfo)method);
|
||||
wrapper.EmitCallvirt = null;
|
||||
wrapper.EmitNewobj = CodeEmitter.Create(OpCodes.Newobj, (ConstructorInfo)method);
|
||||
call = CodeEmitter.Create(OpCodes.Call, (ConstructorInfo)method);
|
||||
callvirt = null;
|
||||
newobj = CodeEmitter.Create(OpCodes.Newobj, (ConstructorInfo)method);
|
||||
}
|
||||
else
|
||||
{
|
||||
wrapper.EmitCall = CodeEmitter.Create(OpCodes.Call, (MethodInfo)method);
|
||||
call = CodeEmitter.Create(OpCodes.Call, (MethodInfo)method);
|
||||
if(originalMethod != null && originalMethod != method)
|
||||
{
|
||||
// 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
|
||||
wrapper.EmitCallvirt = CodeEmitter.Create(OpCodes.Callvirt, (MethodInfo)originalMethod);
|
||||
callvirt = CodeEmitter.Create(OpCodes.Callvirt, (MethodInfo)originalMethod);
|
||||
}
|
||||
else if(method.IsStatic)
|
||||
{
|
||||
// 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
|
||||
{
|
||||
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)
|
||||
|
|
|
@ -918,13 +918,17 @@ namespace NativeCode.java
|
|||
|
||||
public static object loadBootstrapClass(string name, bool initialize)
|
||||
{
|
||||
TypeWrapper type = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(name);
|
||||
type.Finish();
|
||||
if(initialize)
|
||||
TypeWrapper type = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedNameFast(name);
|
||||
if(type != null)
|
||||
{
|
||||
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)
|
||||
|
@ -1685,8 +1689,13 @@ namespace NativeCode.java
|
|||
{
|
||||
public static string getDefaultTimeZoneId()
|
||||
{
|
||||
// HACK return null, classpath then assumes GMT, which is fine by me, for the time being
|
||||
return null;
|
||||
NetSystem.TimeZone currentTimeZone = NetSystem.TimeZone.CurrentTimeZone;
|
||||
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" ?>
|
||||
<!--
|
||||
Copyright (C) 2002 Jeroen Frijters
|
||||
Copyright (C) 2002, 2003 Jeroen Frijters
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -109,7 +109,7 @@
|
|||
<constructor sig="([CII)V" modifiers="public" />
|
||||
<!-- Package private constructor, that we redirect to static helper -->
|
||||
<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 sig="(Ljava/lang/String;)V" modifiers="public">
|
||||
<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;" />
|
||||
</constructor>
|
||||
<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 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 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 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 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 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>
|
||||
<method name="hashCode" sig="()I" modifiers="public">
|
||||
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;)I" />
|
||||
|
@ -220,52 +220,52 @@
|
|||
<redirect name="EndsWith" />
|
||||
</method>
|
||||
<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 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 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 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 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 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 name="intern" sig="()Ljava/lang/String;" modifiers="public">
|
||||
<redirect type="static" name="Intern" sig="(Ljava/lang/String;)Ljava/lang/String;" />
|
||||
</method>
|
||||
<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 name="replace" sig="(CC)Ljava/lang/String;" modifiers="public">
|
||||
<redirect name="Replace" />
|
||||
</method>
|
||||
<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 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 name="subSequence" sig="(II)Ljava/lang/CharSequence;" modifiers="public">
|
||||
<redirect class="StringHelper" type="static" sig="(Ljava/lang/String;II)Ljava/lang/Object;" />
|
||||
</method>
|
||||
<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 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 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 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 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;" />
|
||||
|
@ -280,6 +280,9 @@
|
|||
<newobj class="System.String" name=".ctor" sig="([CII)V" />
|
||||
</invokestatic>
|
||||
</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 only reading fields can be redirected
|
||||
-->
|
||||
|
|
1525
IK.VM.NET/mapxml.cs
1525
IK.VM.NET/mapxml.cs
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -34,6 +34,7 @@ public class JVM
|
|||
private static bool debug = false;
|
||||
private static bool noJniStubs = false;
|
||||
private static bool isStaticCompiler = false;
|
||||
private static bool logClassLoadFailures = false;
|
||||
private static IJniProvider jniProvider;
|
||||
|
||||
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
|
||||
{
|
||||
get
|
||||
|
@ -222,7 +235,7 @@ public class JVM
|
|||
{
|
||||
Assembly.LoadFrom(r);
|
||||
}
|
||||
Console.WriteLine("Loading remapped types");
|
||||
Console.WriteLine("Loading remapped types (1)");
|
||||
loader.LoadRemappedTypes();
|
||||
Console.WriteLine("Compiling class files (1)");
|
||||
foreach(string s in h.Keys)
|
||||
|
@ -253,6 +266,8 @@ public class JVM
|
|||
loader.SetMain(method, target);
|
||||
}
|
||||
}
|
||||
Console.WriteLine("Loading remapped types (2)");
|
||||
loader.LoadRemappedTypesStep2();
|
||||
Console.WriteLine("Compiling class files (2)");
|
||||
loader.AddResources(resources);
|
||||
loader.Save();
|
||||
|
|
|
@ -458,6 +458,10 @@ namespace ikvm.awt
|
|||
{
|
||||
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)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
@ -524,6 +528,62 @@ namespace ikvm.awt
|
|||
{
|
||||
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
|
||||
|
@ -632,6 +692,18 @@ namespace ikvm.awt
|
|||
{
|
||||
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
|
||||
|
@ -757,6 +829,18 @@ namespace ikvm.awt
|
|||
{
|
||||
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
|
||||
|
@ -846,5 +930,17 @@ namespace ikvm.awt
|
|||
// TODO use control.Invoke
|
||||
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\java\net\protocol\ikvmres\Handler.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\Class.java
|
||||
C:\ikvm\classpath\java\lang\StringHelper.java
|
||||
C:\ikvm\classpath\java\lang\VMClassLoader.java
|
||||
C:\ikvm\classpath\java\lang\reflect\Constructor.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\DoubleBufferImpl.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\IntBufferImpl.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\dnd\Autoscroll.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\DragGestureListener.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\peer\DragSourceContextPeer.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\ActionListener.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\WindowListener.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\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\Arc2D.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\PanelPeer.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\ScrollPanePeer.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\BeanContextServices.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\BufferedOutputStream.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\File.java
|
||||
C:\classpath\java\io\FileFilter.java
|
||||
C:\classpath\java\io\FileInputStream.java
|
||||
C:\classpath\java\io\FilenameFilter.java
|
||||
C:\classpath\java\io\FileNotFoundException.java
|
||||
C:\classpath\java\io\FileOutputStream.java
|
||||
C:\classpath\java\io\FilePermission.java
|
||||
C:\classpath\java\io\FileReader.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\PushbackInputStream.java
|
||||
C:\classpath\java\io\PushbackReader.java
|
||||
C:\classpath\java\io\RandomAccessFile.java
|
||||
C:\classpath\java\io\Reader.java
|
||||
C:\classpath\java\io\SequenceInputStream.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\DSAPublicKey.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\RSAPrivateKey.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\KeySpec.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\RSAMultiPrimePrivateCrtKeySpec.java
|
||||
C:\classpath\java\security\spec\RSAOtherPrimeInfo.java
|
||||
C:\classpath\java\security\spec\RSAPrivateCrtKeySpec.java
|
||||
C:\classpath\java\security\spec\RSAPrivateKeySpec.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\SearchControls.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\DirObjectFactory.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\vm\reference\gnu\vm\stack\StackFrame.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\VMObject.java
|
||||
C:\classpath\vm\reference\java\lang\VMSecurityManager.java
|
||||
C:\classpath\vm\reference\java\lang\VMSystem.java
|
||||
C:\classpath\vm\reference\java\lang\VMThrowable.java
|
||||
C:\classpath\vm\reference\java\io\VMObjectStreamClass.java
|
||||
|
|
|
@ -1,31 +1,54 @@
|
|||
/*
|
||||
Copyright (C) 2002 Jeroen Frijters
|
||||
/* FileDescriptor.java -- Opaque file handle class
|
||||
Copyright (C) 1998,2003 Free Software Foundation, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
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. */
|
||||
|
||||
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;
|
||||
|
||||
import system.Console;
|
||||
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 static final FileDescriptor in = new FileDescriptor(Console.OpenStandardInput());
|
||||
|
@ -96,43 +119,57 @@ public final class FileDescriptor
|
|||
return path;
|
||||
}
|
||||
|
||||
static final int Append = 0; // FileMode.Append, FileAccess.Write (FileOutputStream(append = true))
|
||||
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
|
||||
synchronized void open(String path, String mode) throws IOException
|
||||
{
|
||||
if(stream != null)
|
||||
throw new IOException("FileDescriptor already open");
|
||||
if ((path == null) || path.equals(""))
|
||||
throw new IllegalArgumentException("Path cannot be null");
|
||||
try
|
||||
{
|
||||
int fileMode;
|
||||
int fileAccess;
|
||||
switch(mode)
|
||||
if(mode.equals("r"))
|
||||
{
|
||||
case Append:
|
||||
fileMode = FileMode.Append;
|
||||
fileAccess = FileAccess.Write;
|
||||
break;
|
||||
case Write:
|
||||
fileMode = FileMode.Create;
|
||||
fileAccess = FileAccess.Write;
|
||||
break;
|
||||
case Read:
|
||||
fileMode = FileMode.Open;
|
||||
fileAccess = FileAccess.Read;
|
||||
break;
|
||||
case ReadWrite:
|
||||
fileMode = FileMode.OpenOrCreate;
|
||||
fileAccess = FileAccess.ReadWrite;
|
||||
break;
|
||||
default:
|
||||
throw new Error("Invalid mode: " + mode);
|
||||
fileMode = FileMode.Open;
|
||||
fileAccess = FileAccess.Read;
|
||||
}
|
||||
else if(mode.equals("rw"))
|
||||
{
|
||||
fileMode = FileMode.OpenOrCreate;
|
||||
fileAccess = FileAccess.ReadWrite;
|
||||
}
|
||||
else if(mode.equals("rws") || mode.equals("rwd"))
|
||||
{
|
||||
// TODO implement this
|
||||
throw new IllegalArgumentException("rws and rwd not implemented");
|
||||
//fileMode = FileMode.OpenOrCreate;
|
||||
//fileAccess = FileAccess.ReadWrite;
|
||||
}
|
||||
else if(mode.equals("rwa"))
|
||||
{
|
||||
// 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.security.SecurityException();
|
||||
if(false) throw new system.UnauthorizedAccessException();
|
||||
FileStream fs = system.io.File.Open(demanglePath(name), fileMode, fileAccess, FileShare.ReadWrite);
|
||||
return new FileDescriptor(fs);
|
||||
stream = system.io.File.Open(demanglePath(path), fileMode, fileAccess, FileShare.ReadWrite);
|
||||
}
|
||||
catch(system.security.SecurityException x1)
|
||||
{
|
||||
|
@ -153,9 +190,8 @@ public final class FileDescriptor
|
|||
synchronized long getFilePointer() throws IOException
|
||||
{
|
||||
if(stream == null)
|
||||
{
|
||||
throw new IOException();
|
||||
}
|
||||
throw new IOException("Invalid FileDescriptor");
|
||||
|
||||
try
|
||||
{
|
||||
if(false) throw new system.io.IOException();
|
||||
|
@ -171,9 +207,8 @@ public final class FileDescriptor
|
|||
synchronized long getLength() throws IOException
|
||||
{
|
||||
if(stream == null)
|
||||
{
|
||||
throw new IOException();
|
||||
}
|
||||
throw new IOException("Invalid FileDescriptor");
|
||||
|
||||
try
|
||||
{
|
||||
if(false) throw new system.io.IOException();
|
||||
|
@ -186,16 +221,19 @@ public final class FileDescriptor
|
|||
// 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)
|
||||
{
|
||||
throw new IOException();
|
||||
}
|
||||
throw new IOException("Invalid FileDescriptor");
|
||||
|
||||
if (len < 0)
|
||||
throw new IllegalArgumentException("Length cannot be less than zero " +
|
||||
len);
|
||||
|
||||
try
|
||||
{
|
||||
if(false) throw new system.io.IOException();
|
||||
stream.SetLength(length);
|
||||
stream.SetLength(len);
|
||||
}
|
||||
catch(system.io.IOException x)
|
||||
{
|
||||
|
@ -204,16 +242,27 @@ public final class FileDescriptor
|
|||
// 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)
|
||||
{
|
||||
throw new IOException();
|
||||
}
|
||||
throw new IOException("Invalid FileDescriptor");
|
||||
|
||||
if ((whence != SET) && (whence != CUR) && (whence != END))
|
||||
throw new IllegalArgumentException("Invalid whence value: " + whence);
|
||||
|
||||
try
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -222,16 +271,15 @@ public final class FileDescriptor
|
|||
// 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)
|
||||
{
|
||||
throw new IOException();
|
||||
}
|
||||
throw new IOException("Invalid FileDescriptor");
|
||||
|
||||
try
|
||||
{
|
||||
if(false) throw new system.io.IOException();
|
||||
return stream.Read(buf, offset, length);
|
||||
return stream.ReadByte();
|
||||
}
|
||||
catch(system.io.IOException x)
|
||||
{
|
||||
|
@ -240,16 +288,29 @@ public final class FileDescriptor
|
|||
// 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)
|
||||
{
|
||||
throw new IOException();
|
||||
}
|
||||
throw new IOException("Invalid FileDescriptor");
|
||||
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -258,19 +319,16 @@ public final class FileDescriptor
|
|||
// 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)
|
||||
{
|
||||
throw new IOException();
|
||||
throw new IOException("Invalid FileDescriptor");
|
||||
}
|
||||
try
|
||||
{
|
||||
if(false) throw new system.io.IOException();
|
||||
// TODO this is broken, because non-seekable streams should support skip as well...
|
||||
// (and I don't think we should seek past EOF here)
|
||||
stream.Seek(n, SeekOrigin.Current);
|
||||
return n;
|
||||
stream.WriteByte((byte)b);
|
||||
}
|
||||
catch(system.io.IOException x)
|
||||
{
|
||||
|
@ -278,4 +336,45 @@ public final class FileDescriptor
|
|||
}
|
||||
// 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
|
||||
{
|
||||
Class c = Class.loadBootstrapClass(name, false);
|
||||
if(c == null)
|
||||
{
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
return c;
|
||||
return Class.loadBootstrapClass(name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -134,19 +134,27 @@ public final class Field extends AccessibleObject implements Member
|
|||
/**
|
||||
* Compare two objects to see if they are semantically equivalent.
|
||||
* Two Fields are semantically equivalent if they have the same declaring
|
||||
* class, name, and type. Since you can't creat a Field except through
|
||||
* the VM, this is just the == relation.
|
||||
* class, name, and type.
|
||||
*
|
||||
* @param o the object to compare to
|
||||
* @return <code>true</code> if they are equal; <code>false</code> if not
|
||||
*/
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if(o instanceof Field)
|
||||
{
|
||||
return fieldCookie == ((Field)o).fieldCookie;
|
||||
}
|
||||
return false;
|
||||
if(!(o instanceof Field))
|
||||
return false;
|
||||
|
||||
Field f = (Field)o;
|
||||
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)
|
||||
{
|
||||
// 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))
|
||||
return false;
|
||||
|
||||
|
@ -206,6 +185,9 @@ public final class Method extends AccessibleObject implements Member
|
|||
if(declaringClass != m.declaringClass)
|
||||
return false;
|
||||
|
||||
if(getReturnType() != m.getReturnType())
|
||||
return false;
|
||||
|
||||
Class[] params1 = getParameterTypes();
|
||||
Class[] params2 = m.getParameterTypes();
|
||||
if(params1.length != params2.length)
|
||||
|
|
|
@ -146,15 +146,15 @@ public class Starter
|
|||
{
|
||||
if(args[i][0] == '-')
|
||||
{
|
||||
if(args[i] == "-help")
|
||||
if(args[i] == "-help" || args[i] == "-?")
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if(args[i] == "-save")
|
||||
else if(args[i] == "-Xsave")
|
||||
{
|
||||
saveAssembly = true;
|
||||
}
|
||||
else if(args[i] == "-time")
|
||||
else if(args[i] == "-Xtime")
|
||||
{
|
||||
new Timer();
|
||||
}
|
||||
|
@ -179,6 +179,10 @@ public class Starter
|
|||
{
|
||||
java.lang.System.setProperty("ikvm.boot.class.path", args[i].Substring(16));
|
||||
}
|
||||
else if(args[i] == "-Xlogclf")
|
||||
{
|
||||
JVM.LogClassLoadFailures = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
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();
|
||||
Console.Error.WriteLine("where options include:");
|
||||
Console.Error.WriteLine(" -help display this message");
|
||||
Console.Error.WriteLine(" -cp -classpath <directories and zip/jar files separated by ;>");
|
||||
Console.Error.WriteLine(" -? -help display this message");
|
||||
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(" -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(" -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(" -Xlogclf log class load failures");
|
||||
return 1;
|
||||
}
|
||||
try
|
||||
|
|
Загрузка…
Ссылка в новой задаче