📄 objectstreamclassimpl.c
字号:
const char* orig; if (!FIELD_RESOLVED(fld)) { /* This is like so: Ljava/lang/String; */ orig = ((Utf8Const*)(void*)fld->type)->data; str = KMALLOC(strlen(orig) + 1); return (str ? strcpy(str, orig) : 0); } else if (!CLASS_IS_PRIMITIVE(FIELD_TYPE(fld))) { /* This is like so: java.lang.String */ orig = FIELD_TYPE(fld)->name->data; if (orig[0] == '[') { /* arrays should be fine */ str = KMALLOC(strlen(orig) + 1); if (str) classname2pathname(orig, str); return (str); } else { str = KMALLOC(strlen(orig) + 3); if (!str) return 0; strcpy(str, "L"); strcat(str, orig); strcat(str, ";"); classname2pathname(str, str); return (str); } } else { orig = CLASS_PRIM_NAME(FIELD_TYPE(fld))->data; str = KMALLOC(strlen(orig) + 1); return (str ? strcpy(str, orig) : 0); }}staticchar*getMethodDesc(Method* mth){ return (pathname2ClassnameCopy(METHOD_SIGD(mth)));}/* * get this class's name in the form pkg.subpkg.name */staticchar*getClassName(Hjava_lang_Class* cls){ return (pathname2ClassnameCopy(cls->name->data));}jlongkaffe_io_ObjectStreamClassImpl_getSerialVersionUID0(Hjava_lang_Class* cls){ Field* fld; Method* mth; SHA1_CTX c; unsigned char md[SHA_DIGEST_LENGTH]; int mod; int i; uidItem* base = 0; int len; errorInfo einfo; jshort tmp; char *classname; /* For GCJ compatibility, we cannot hardcode this in java/lang/Class * This number won't change as long as the universe exists, so it's * safe to keep it here. */ if (cls == ClassClass) { return (3206093459760846163LL); } /* Lookup _local_ field serialVersionUID */ for (fld = CLASS_SFIELDS(cls), i = CLASS_NSFIELDS(cls); i-- > 0; fld++) { if (utf8ConstEqual (serialVersionUIDName, fld->name) && (fld->accflags & (ACC_STATIC|ACC_FINAL)) == (ACC_STATIC|ACC_FINAL)) { Hjava_lang_Class* ftype; ftype = resolveFieldType(fld, cls, &einfo); if (ftype == 0) { throwError(&einfo); } /* See JDC Bug 4431318: The serialization spec does * not state what should occur if serialVersionUID is * declared to be of a type other than long; throwing * an IllegalArgumentException, while not particularly * graceful, is not strictly in violation of the spec. * A reasonable solution may be for serialization to * throw InvalidClassExceptions in cases like this. * * Use JDK1.1 behavior until serialization spec states what * should occur. */ if (ftype == longClass) { return (*(jlong*)FIELD_ADDRESS(fld)); } else { break; } } } /* Okay - since there's no field we have to compute the UID */ /* Allocate enough uidItem space for all our needs */ len = CLASS_NMETHODS(cls); if (len < CLASS_NFIELDS(cls)) { len = CLASS_NFIELDS(cls); } if (len < cls->interface_len) { len = cls->interface_len; } if (len > 0) { base = KMALLOC(sizeof(uidItem) * len); if (!base) { postOutOfMemory(&einfo); throwError(&einfo); } } SHA1Init(&c); /* Class -> name(UTF), modifier(INT) */ /* we store the classname with slashes as path names, * but here we must use the dotted form */ classname = getClassName(cls); if (!classname) { KFREE(base); postOutOfMemory(&einfo); throwError(&einfo); } tmp = htons(strlen(classname)); SHA1Update(&c, (char*)&tmp, sizeof(tmp)); SHA1Update(&c, classname, strlen(classname)); KFREE(classname); mod = htonl((int)cls->accflags & (ACC_ABSTRACT|ACC_FINAL|ACC_INTERFACE|ACC_PUBLIC)); SHA1Update(&c, (char*)&mod, sizeof(mod)); /* Name of each interface (sorted): UTF */ /* Don't include the interfaces that arrays implement because Sun * apparently doesn't include them either. * This is like Class.getInterfaces() */ if (!CLASS_IS_ARRAY(cls) && cls->interface_len > 0) { for (i = cls->interface_len-1; i >= 0; i--) { base[i].name = getClassName(cls->interfaces[i]); base[i].modifier = -1; base[i].desc = 0; if (!base[i].name) { int j = cls->interface_len; for (j--; j > i; j--) KFREE(base[j].name); KFREE(base); postOutOfMemory(&einfo); throwError(&einfo); } } addToSHA(&c, base, cls->interface_len); /* Free all the interface name strings */ i = cls->interface_len; for (i--; i >= 0; i--) { KFREE(base[i].name); } } /* Each field (sorted) -> */ i = CLASS_NFIELDS(cls); if (i > 0) { fld = CLASS_FIELDS(cls); for (i--; i >= 0; i--, fld++) { if ((fld->accflags & ACC_PRIVATE) != 0 && ((fld->accflags & (ACC_STATIC|ACC_TRANSIENT)) != 0)) { base[i].name = 0; base[i].desc = 0; } else { base[i].name = fld->name->data; base[i].modifier = (int)fld->accflags & ACC_MASK; base[i].desc = getFieldDesc(fld); if (!base[i].desc) { int j = CLASS_NFIELDS(cls); for (j--; j > i; j--) KFREE(base[j].desc); KFREE(base); postOutOfMemory(&einfo); throwError(&einfo); } } } addToSHA(&c, base, CLASS_NFIELDS(cls)); /* free descriptors */ i = CLASS_NFIELDS(cls); for (i--; i >= 0; i--) { KFREE(base[i].desc); } } if (CLASS_NMETHODS(cls) > 0) { /* Class initializer -> */ if (findMethodLocal(cls, init_name, void_signature) != 0) { base[0].name = "<clinit>"; base[0].modifier = ACC_STATIC; base[0].desc = "()V"; addToSHA(&c, base, 1); } /* Each non-private constructor (sorted) -> */ i = CLASS_NMETHODS(cls); mth = CLASS_METHODS(cls); for (i--; i >= 0; i--, mth++) { if ((mth->accflags & (ACC_CONSTRUCTOR|ACC_PRIVATE)) != ACC_CONSTRUCTOR) { base[i].name = 0; } else { base[i].name = mth->name->data; } base[i].modifier = (int)mth->accflags & ACC_MASK; base[i].desc = getMethodDesc(mth); if (!base[i].desc) { int j = CLASS_NMETHODS(cls); for (j--; j > i; j--) KFREE(base[j].desc); KFREE(base); postOutOfMemory(&einfo); throwError(&einfo); } } addToSHA(&c, base, CLASS_NMETHODS(cls)); /* Free all the descriptor strings */ i = CLASS_NMETHODS(cls); for (i--; i >= 0; i--) { KFREE(base[i].desc); } /* NB: we can't reuse the base array here because * addToSHA has qsorted it. */ /* Each non-private method (sorted) -> */ i = CLASS_NMETHODS(cls); mth = CLASS_METHODS(cls); for (i--; i >= 0; i--, mth++) { /* skip private methods, constructors, and * <clinit> again. Do not include <clinit> twice */ if (((mth->accflags & (ACC_CONSTRUCTOR|ACC_PRIVATE)) != 0) || (utf8ConstEqual(mth->name, init_name) && utf8ConstEqual(METHOD_SIG(mth), void_signature))) { base[i].name = 0; } else { base[i].name = mth->name->data; } base[i].modifier = (int)mth->accflags & ACC_MASK; base[i].desc = getMethodDesc(mth); if (!base[i].desc) { int j = CLASS_NMETHODS(cls); for (j--; j > i; j--) KFREE(base[j].desc); KFREE(base); postOutOfMemory(&einfo); throwError(&einfo); } } addToSHA(&c, base, CLASS_NMETHODS(cls)); /* Free all the descriptor strings */ i = CLASS_NMETHODS(cls); for (i--; i >= 0; i--) { KFREE(base[i].desc); } } SHA1Final(md, &c); KFREE(base); return ( (jlong)md[0] | ((jlong)md[1] << 8) | ((jlong)md[2] << 16) | ((jlong)md[3] << 24) | ((jlong)md[4] << 32) | ((jlong)md[5] << 40) | ((jlong)md[6] << 48) | ((jlong)md[7] << 56) );}jboolkaffe_io_ObjectStreamClassImpl_hasWriteObject0(struct Hjava_lang_Class* clazz){ if (findMethodLocal(clazz, writeObjectName, ObjectOutputStreamSig) == 0) { return (false); } else { return (true); }}staticHjava_lang_Class*findDefaultSerialization(Hjava_lang_Class* clazz){ char* name; Hjava_lang_Class* nclazz; errorInfo einfo; name = KMALLOC(strlen(clazz->name->data) + 22); if (!name) { postOutOfMemory(&einfo); throwError(&einfo); } strcpy(name, clazz->name->data); strcat(name, "$DefaultSerialization"); /* Use the JNI because it handles errors */ nclazz = lookupClass(name, clazz->loader, &einfo); if (nclazz == 0) { discardErrorInfo(&einfo); nclazz = clazz; } KFREE(name); return (nclazz);}/* * Create an instance of the inner class using the given object. This is * slightly dodgy since it just finds the first <init> method which takes * an argument - but then there shouldn't be any others. */staticHjava_lang_Object*newSerialObject(Hjava_lang_Class* clazz, Hjava_lang_Object* obj){ int n; Method* mptr; n = CLASS_NMETHODS(clazz); for (mptr = CLASS_METHODS(clazz); --n >= 0; ++mptr) { if (utf8ConstEqual(mptr->name, constructor_name) && !utf8ConstEqual(METHOD_SIG(mptr), void_signature)) { extern JNIEnv Kaffe_JNIEnv; JNIEnv *env = &Kaffe_JNIEnv; return ((Hjava_lang_Object*)(*env)->NewObject(env, clazz, (jmethodID)mptr, obj)); } } return (0);}staticintcompare(const void* o, const void* t){ Field* one = *(Field**)o; Field* two = *(Field**)t; if (FIELD_ISREF(one)) { if (!FIELD_ISREF(two)) { return (1); } } else if (FIELD_ISREF(two)) { return (-1); } return (strcmp(one->name->data, two->name->data));}staticHArrayOfObject*getFields(struct Hkaffe_io_ObjectStreamClassImpl* cls){ Hjava_lang_Class* clazz; int len; Field* fld; int cnt; HArrayOfObject* array; int i; /* Check for the default serialization implemented as an inner-class */ if (unhand(cls)->iclazz == 0) { unhand(cls)->iclazz = findDefaultSerialization(unhand(cls)->clazz); } clazz = unhand(cls)->iclazz; /* Count the number of fields we need to store */ len = CLASS_NIFIELDS(clazz); fld = CLASS_IFIELDS(clazz); cnt = 0; for (i = 0; i < len; i++, fld++) { if ((fld->accflags & ACC_TRANSIENT) != 0) { continue; } /* Skip innerclass nonsense */ if (strncmp(fld->name->data, "this$", 5) == 0) { continue; } cnt++; } /* Build an array of those fields */ array = (HArrayOfObject*)newArray(ptrType, cnt); cnt = 0; fld = CLASS_IFIELDS(clazz); for (i = 0; i < len; i++, fld++) { if ((fld->accflags & ACC_TRANSIENT) != 0) { continue; } /* Skip innerclass nonsense */ if (strncmp(fld->name->data, "this$", 5) == 0) { continue; } unhand_array(array)->body[cnt] = (void*)fld; cnt++; } qsort(unhand_array(array)->body, cnt, sizeof(void*), compare); return (array);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -