/* Purpose: Read the integers (stored one per line) from a text file to a data linked list structure Parameters: filename - The filename of the file to open. head - The address of a pointer to be set to point to the first element Return value: The number of integers stored Function calls: Direct function calls - assert(), fopen(), fscanf(), malloc(), fclose() Via checkPtr macro - fprintf(), exit() Asserts: fileName cannot point to nothing head cannot be NULL Revision history: 1.0 - 11/04/2014 created by Joshua Tyler */ unsigned int datlCreateFromFile(char* fileName, dataListElement** head) { assert(fileName != NULL); assert(head != NULL); FILE *inputFile = fopen(fileName,"r"); checkPtr(inputFile); unsigned int count = 0; int currentNum; dataListElement *currentItem = NULL; dataListElement *temp; *head = NULL; while( fscanf(inputFile,"%d", ¤tNum) == 1) { count++; temp = (dataListElement *) malloc(sizeof(dataListElement)); checkPtr(temp); /* If this is the first item in the list, set the head pointer */ if(currentItem == NULL) { *head = currentItem = temp; } else { currentItem->next = temp; currentItem = temp; } currentItem->data = currentNum; currentItem->next = NULL; } fclose(inputFile); return count; }
/** * Allocate an object and execute the constructor. * * @param cname the name of the class to be instantiated (may be 0 if cc is != 0) * @param loader the class loader that's to be used to lookup the class * @param cc the class to be instantiated (may be 0 if cname is != 0) * @param signature the signature of the constructor to be executed * @param argptr arguments to be passed to the constructor * * @throws InstantiationException if class is an interface or abstract * @throws NoSuchMethodError if the specified constructor cannot be found * * @return the newly allocated object */ Hjava_lang_Object* execute_java_constructor_v(const char* cname, Hjava_lang_ClassLoader* loader, Hjava_lang_Class* cc, const char* signature, va_list argptr) { Hjava_lang_Object* obj; Method* mb; jvalue retval; errorInfo info; Utf8Const* sig; if (cc == 0) { char *buf; /* Convert "." to "/" and lookup class */ buf = checkPtr(KMALLOC(strlen(cname) + 1)); classname2pathname(cname, buf); cc = lookupClass(buf, loader, &info); KFREE(buf); if (!cc) { throwError(&info); } } /* We cannot construct interfaces or abstract classes */ if (CLASS_IS_INTERFACE(cc) || CLASS_IS_ABSTRACT(cc)) { throwException(InstantiationException(cc->name->data)); } if (cc->state < CSTATE_USABLE) { if (processClass(cc, CSTATE_COMPLETE, &info) == false) { throwError(&info); } } sig = checkPtr(utf8ConstFromString(signature)); mb = findMethodLocal(cc, constructor_name, sig); utf8ConstRelease(sig); if (mb == 0) { throwException(NoSuchMethodError(constructor_name->data)); } obj = newObject(cc); assert(obj != 0); /* Make the call */ KaffeVM_callMethodV(mb, METHOD_NATIVECODE(mb), obj, argptr, &retval); return (obj); }
/* Purpose: Add a message to a debug linked list Parameters: list - the list header of the list to add it to value and event - parameters to save into the list lastRep - if TRUE this function is being called on the last repitition of the store/search action Return value: None Function calls: Direct function calls - assert(), malloc() Via checkPtr macro - fprintf(), exit() Asserts: list cannot be NULL Revision history: 1.0 - 16/04/2014 JT adapted from deblAddMsg() in hashed.cpp */ void deblAddMsg(debugList *list, int value, debugEvent event, unsigned int lastRep) { assert(list != NULL); /* If this is not the last repitition, return to avoid repeat messages */ if(!lastRep) return; debugListElement *elementToAdd; /* Allocate space for an element */ elementToAdd = (debugListElement *)malloc(sizeof(debugListElement)); checkPtr(elementToAdd); /* Set values of new element */ elementToAdd->value = value; elementToAdd->event = event; elementToAdd->next = NULL; /* Add element to the end of the list */ if(list->first == NULL) { list->first = elementToAdd; list->last = elementToAdd; } else { list->last->next = elementToAdd; list->last = elementToAdd; } }
/** * Call a Java static method on a class from native code. * * @param cname name of the class whose method is to be called * @param loader the class loader that's to be used to lookup the class * @param method_name the name of the method to be called * @param signature the signature of the method to be called * @param argptr the arguments to be passed to the method * * @throws NuSuchMethodError if method cannot be found * * @return the return value of the method */ void do_execute_java_class_method_v(jvalue *retval, const char* cname, Hjava_lang_ClassLoader* loader, const char* method_name, const char* signature, va_list argptr) { Hjava_lang_Class* clazz; errorInfo info; Method* mb = NULL; char *buf; /* Convert "." to "/" and lookup class */ buf = checkPtr(KMALLOC(strlen(cname) + 1)); classname2pathname(cname, buf); clazz = lookupClass(buf, loader, &info); KFREE(buf); /* Get method */ if (clazz != NULL) { mb = lookupClassMethod(clazz, method_name, signature, false, &info); } if (mb == NULL) { throwError(&info); } /* Method must be static to invoke it here */ if ((mb->accflags & ACC_STATIC) == 0) { throwException(NoSuchMethodError(method_name)); } /* Make the call */ KaffeVM_callMethodV(mb, METHOD_NATIVECODE(mb), NULL, argptr, retval); }
void _sphere_finalizer(SEXP Rextp) { checkPtr(Rextp, sphere_type_tag); STGM::CBoolSphereSystem *sp = (STGM::CBoolSphereSystem *)(R_ExternalPtrAddr(Rextp)); _free_spheres(sp); R_ClearExternalPtr(Rextp); }
/* * pushSig() * Pushes a new signature on the Stack */ SigStack* pushSig(SigStack* sigs, const char* sig) { SigStack* new_sig = checkPtr(gc_malloc(sizeof(SigStack), KGC_ALLOC_VERIFIER)); new_sig->sig = sig; new_sig->next = sigs; return new_sig; }
/* Purpose: Creates an array and initialises all elements to empty Parameters: size - the number of elements to have in the array Return value: The header of the array Function calls: Direct function calls - assert(), calloc(). Via checkPtr macro - fprintf(), exit() Asserts: Size cannot be zero. Revision history: 1.0 - 15/04/2014 adapted from htblCreate() by Joshua Tyler */ array aryCreate(unsigned int size) { assert(size > 0); array header; header.data = (int *) calloc(size, sizeof(int)); // We're using calloc, so all elements will be 0 checkPtr(header.data); header.size = size; return header; }
/** * This function is an helper for lookupField. It creates a UTF string and invoke lookupField * with it. * * */ Field* KNI_lookupFieldC(struct Hjava_lang_Class* clazz, const char* fieldName, bool isStatic, errorInfo* einfo) { Utf8Const *fieldUTF; Field *field; checkPtr(fieldUTF = utf8ConstFromString(fieldName)); field = lookupClassField(clazz, fieldUTF, isStatic, einfo); utf8ConstRelease(fieldUTF); return field; }
/** * Signal an error by creating the object and throwing the exception. * See also SignalErrorf * * @param cname the name of the class of the exception object to be created * @param str the message to be passed to the constructor of the exception object */ void SignalError(const char* cname, const char* str) { Hjava_lang_Throwable* obj; if (str == NULL || *str == '\0') { obj = (Hjava_lang_Throwable*)execute_java_constructor(cname, NULL, NULL, ERROR_SIGNATURE0); } else { obj = (Hjava_lang_Throwable*)execute_java_constructor(cname, NULL, NULL, ERROR_SIGNATURE, checkPtr(stringC2Java(str))); } throwException(obj); }
/* * allocate memory for a block info and fill in with default values */ BlockInfo* createBlock(const Method* method) { int i; BlockInfo* binfo = checkPtr((BlockInfo*)gc_malloc(sizeof(BlockInfo), KGC_ALLOC_VERIFIER)); binfo->startAddr = 0; binfo->status = IS_INSTRUCTION | START_BLOCK; /* not VISITED or CHANGED */ /* allocate memory for locals */ if (method->localsz > 0) { binfo->locals = checkPtr(gc_malloc(method->localsz * sizeof(Type), KGC_ALLOC_VERIFIER)); for (i = 0; i < method->localsz; i++) { binfo->locals[i] = *getTUNSTABLE(); } } else { binfo->locals = NULL; } /* allocate memory for operand stack */ binfo->stacksz = 0; if (method->stacksz > 0) { binfo->opstack = checkPtr(gc_malloc(method->stacksz * sizeof(Type), KGC_ALLOC_VERIFIER)); for (i = 0; i < method->stacksz; i++) { binfo->opstack[i] = *getTUNSTABLE(); } } else { binfo->opstack = NULL; } return binfo; }
SEXP IntersectSphereSystem(SEXP ext, SEXP R_n, SEXP R_z, SEXP R_intern) { checkPtr(ext, sphere_type_tag); STGM::CVector3d n(REAL(R_n)[0],REAL(R_n)[1],REAL(R_n)[2]); STGM::CPlane plane( n , asReal(R_z)); STGM::CBoolSphereSystem *sp = static_cast<STGM::CBoolSphereSystem *>(getExternalPtr(ext)); if(PL>100) Rprintf("Intersect with plane: %d \n", sp->refObjects().size()); STGM::Intersectors<STGM::CSphere>::Type objects; int intern = asInteger(AS_INTEGER(R_intern)); sp->IntersectWithPlane(objects,plane,intern); return convert_R_Circles(objects); }
/* Purpose: Write statistics to an output text file in CSV format Parameters: fileName - the name of the output file to append to noStored, noSearched, noFound, timeToStore, timeToSearch - parameters to output Return value: None Function calls: Direct function calls - assert(), fopen(), fprintf(), fclose() Via checkPtr macro - fprintf(), exit() Asserts: fileName cannot be NULL Revision history: 1.0 - 14/04/2014 created by Joshua Tyler 2.0 - 15/04/2014 JT added the filename as a parameter */ void printAddToFile(char *fileName, unsigned int noStored, unsigned int noSearched, unsigned int noFound, double timeToStore, double timeToSearch) { assert(fileName != NULL); /* Open the file */ FILE *outputFile; outputFile = fopen(fileName,"a"); checkPtr(outputFile); /* Output the data */ fprintf(outputFile,"%d,%d,%d,%e,%e\n", noStored, noSearched, noFound, timeToStore, timeToSearch); /* Close the file */ fclose(outputFile); }
SEXP GetSphereSystem(SEXP ext) { checkPtr(ext, sphere_type_tag); STGM::CBoolSphereSystem *sp = (STGM::CBoolSphereSystem *)(getExternalPtr(ext)); SEXP R_spheres = R_NilValue; STGM::Spheres &spheres = sp->refObjects(); PROTECT(R_spheres = convert_R_SphereSystem(spheres,sp->box())); setAttrib(R_spheres, install("eptr"), ext); SET_CLASS_NAME(R_spheres,"spheres"); UNPROTECT(1); return R_spheres; }
struct Hjava_lang_Class* java_lang_VMClass_loadArrayClass(struct Hjava_lang_String* str, struct Hjava_lang_ClassLoader* loader) { errorInfo einfo; Hjava_lang_Class* clazz; Utf8Const *utf8buf; const char *buf; int jlen; jchar *js; /* * NB: internally, we store class names as path names (with slashes * instead of dots. However, we must also prevent calls to * "java/lang/Object" or "[[Ljava/lang/Object;" from succeeding. * Since class names cannot have slashes, we reject all attempts * to look up names that do. Awkward. Inefficient. */ js = STRING_DATA(str); jlen = STRING_SIZE(str); while (--jlen > 0) { if (*js++ == '/') { postExceptionMessage(&einfo, JAVA_LANG(ClassNotFoundException), "Cannot have slashes - use dots instead."); throwError(&einfo); } } /* Convert string to utf8, converting '.' to '/' */ utf8buf = checkPtr(stringJava2Utf8ConstReplace(str, '.', '/')); buf = utf8buf->data; clazz = loadArray(utf8buf, loader, &einfo); /* if an error occurred, throw an exception */ if (clazz == 0) { utf8ConstRelease(utf8buf); throwError(&einfo); } utf8ConstRelease(utf8buf); return clazz; }
int main(int argc, char * argv[]) { // Define constants const int nArgs = 6; // Process arguments int c, timeCol=0, valueCol=1; extern char *optarg; char * dataFile, * basisFile, * priorFile, * idString=NULL; short readID = 0; int kSmooth = 8; int maxIter = 1e3; double nu=5; double tol=1e-9; double missingCode = 99.999; int minObs = 10; int basisRows, basisCols, dataRows; int i; // Parse options while ( (c=getopt(argc, argv, "c:d:i:m:n:s:t:h")) != -1 ) { switch(c) { case 'h': puts(kHelpMessage); return 0; case 'c': valueCol = atoi(optarg); valueCol = (valueCol < 0) ? 0 : valueCol; break; case 'd': nu = atof(optarg); nu = (nu < 1) ? 1 : nu; break; case 'i': idString = optarg; readID = 1; break; case 'm': missingCode = atof(optarg); break; case 'n': minObs = atoi(optarg); break; case 's': kSmooth = atoi(optarg); kSmooth = (trunc(log2(kSmooth))-log2(kSmooth) > 1e-16) ? (int) gsl_pow_int(2, trunc(log2(kSmooth))) : kSmooth; break; case 't': timeCol = atoi(optarg); timeCol = (timeCol < 0) ? 1 : timeCol; break; case '?': if ( isprint(optopt) ) fprintf(stderr, "Unknown argument '%c'\n", optopt); else fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); exit(1); break; default: abort(); } } // Parse positional arguments if (argc-optind < nArgs) { fprintf(stderr, "Not enough arguments\n"); exit(1); } // Get file names and dimensions basisFile = argv[optind]; basisRows = atoi( argv[optind+1] ); basisCols = atoi( argv[optind+2] ); dataFile = argv[optind+3]; dataRows = atoi( argv[optind+4] ); priorFile = argv[optind + 5]; if (readID == 0) { idString = dataFile; } // Read basis to allocated matrix double* basisMat; basisMat = malloc(basisCols * basisRows * sizeof(double)); checkPtr(basisMat, "out of memory"); readToDoubleMatrix(basisFile, basisRows, basisCols, basisMat); // Read times to vector double* timeVec; timeVec = malloc(dataRows * sizeof(double)); if (timeVec==NULL) { fprintf(stderr, "Error -- out of memory\n"); exit(1); } int timesRead = readToDoubleVectorDynamic(dataFile, dataRows, timeCol, &timeVec); // Check for valid first time if (isnan(timeVec[0])) { fprintf(stderr, "Error -- NaN at first time; aborting\n"); exit(1); } // Read y values to vector double* yVec; yVec = malloc(dataRows * sizeof(double)); if (yVec==NULL) { fprintf(stderr, "Error -- out of memory\n"); exit(1); } int obsRead = readToDoubleVectorDynamic(dataFile, dataRows, valueCol, &yVec); // Check for valid first obs if (isnan(yVec[0])) { fprintf(stderr, "Error -- NaN at first observation; aborting\n"); exit(1); } // Check for agreement between timesRead and obsRead if (timesRead != obsRead) { fprintf(stderr, "Error -- differing number of entries "); fprintf(stderr, "in time and data columns\n"); exit(1); } // Read prior to vector double * priorVec; priorVec = malloc( (basisCols-1) * sizeof(double)); if (priorVec==NULL) { fprintf(stderr, "Error -- out of memory\n"); exit(1); } readToDoubleVector(priorFile, basisCols-1, 0, priorVec); /* * Handle coded missing values and restructure times */ int nObs = 0; int * validInd; validInd = calloc(sizeof(int), obsRead); // Find valid indices for (i=0; i<obsRead; i++) { if (yVec[i] != missingCode) { validInd[nObs]=i; nObs++; } } // Check for minimum number of observations if (nObs < minObs) { fprintf(stderr, "Error -- read %d obs, minimum to process is %d\n", nObs, minObs); exit(1); } // Move valid data to head of timeVec and yVec for (i=0; i<nObs; i++) { yVec[i] = yVec[validInd[i]]; timeVec[i] = timeVec[validInd[i]]; } // Setup variables for estimation double logPosterior_l, logLikelihood_l, tau_l; double logPosterior_m, logLikelihood_m, tau_m; double * coef_l, * coef_m; coef_l = malloc(kSmooth * sizeof(double)); if (coef_l==NULL) { fprintf(stderr, "Error -- out of memory\n"); exit(1); } coef_m = malloc(basisCols * sizeof(double)); if (coef_m==NULL) { fprintf(stderr, "Error -- out of memory\n"); exit(1); } // Run wavelet model with t residuals for full basis int iter_m; iter_m = lmT(basisMat, basisRows, basisCols, yVec, nObs, timeVec, priorVec, nu, basisCols, maxIter, tol, &logPosterior_m, &logLikelihood_m, coef_m, &tau_m); // Run wavelet model with t residuals for restricted (smooth) basis int iter_l; iter_l = lmT(basisMat, basisRows, basisCols, yVec, nObs, timeVec, priorVec, nu, kSmooth, maxIter, tol, &logPosterior_l, &logLikelihood_l, coef_l, &tau_l); // Calculate test statistics (LLR & LPR) double llr, lpr; llr = logLikelihood_m - logLikelihood_l; llr *= 2; lpr = logPosterior_m - logPosterior_l; /* * Print output */ // Basic information fprintf(stdout, "%s %d %d %d %g ", idString, nObs, basisCols, kSmooth, nu); // Test statistics fprintf(stdout, "%g %g ", llr, lpr); // Other statistics fprintf(stdout, "%g ", sqrt(tau_m)); // Coefficients for k = 1..m for (i=0; i<basisCols; i++) fprintf(stdout, "%g ", coef_m[i]); fprintf(stdout, "\n"); /* * Free allocated memory */ // Free basisMat free(basisMat); basisMat = NULL; // Free timeVec & yVec free(timeVec); timeVec=NULL; free(yVec); yVec=NULL; // Free coef vecs and prior vec free(coef_l); coef_l=NULL; free(coef_m); coef_m=NULL; free(priorVec); priorVec=NULL; return 0; }
//! Simplify the WKB-geometry using the specified tolerance bool QgsMapToPixelSimplifier::simplifyWkbGeometry( int simplifyFlags, SimplifyAlgorithm simplifyAlgorithm, QGis::WkbType wkbType, QgsConstWkbPtr sourceWkbPtr, QgsWkbPtr targetWkbPtr, int &targetWkbSize, const QgsRectangle &envelope, double map2pixelTol, bool writeHeader, bool isaLinearRing ) { bool isGeneralizable = true; bool result = false; // Save initial WKB settings to use when the simplification creates invalid geometries QgsConstWkbPtr sourcePrevWkbPtr( sourceWkbPtr ); QgsWkbPtr targetPrevWkbPtr( targetWkbPtr ); int targetWkbPrevSize = targetWkbSize; // Can replace the geometry by its BBOX ? if (( simplifyFlags & QgsMapToPixelSimplifier::SimplifyEnvelope ) && isGeneralizableByMapBoundingBox( envelope, map2pixelTol ) ) { isGeneralizable = generalizeWkbGeometryByBoundingBox( wkbType, sourceWkbPtr, targetWkbPtr, targetWkbSize, envelope, writeHeader ); if ( isGeneralizable ) return true; } if ( !( simplifyFlags & QgsMapToPixelSimplifier::SimplifyGeometry ) ) isGeneralizable = false; // Write the main header of the geometry if ( writeHeader ) { QgsWKBTypes::Type geometryType = sourceWkbPtr.readHeader(); targetWkbPtr << ( char ) QgsApplication::endian() << QgsWKBTypes::flatType( geometryType ); targetWkbSize += targetWkbPtr - targetPrevWkbPtr; } unsigned int flatType = QGis::flatType( wkbType ); // Write the geometry if ( flatType == QGis::WKBLineString || isaLinearRing ) { QgsWkbPtr savedTargetWkbPtr( targetWkbPtr ); double x = 0.0, y = 0.0, lastX = 0, lastY = 0; QgsRectangle r; r.setMinimal(); int skipZM = ( QGis::wkbDimensions( wkbType ) - 2 ) * sizeof( double ); Q_ASSERT( skipZM >= 0 ); int numPoints; sourceWkbPtr >> numPoints; if ( numPoints <= ( isaLinearRing ? 5 : 2 ) ) isGeneralizable = false; QgsWkbPtr numPtr( targetWkbPtr ); int numTargetPoints = 0; targetWkbPtr << numTargetPoints; targetWkbSize += 4; bool isLongSegment; bool hasLongSegments = false; //-> To avoid replace the simplified geometry by its BBOX when there are 'long' segments. bool badLuck = false; // Check whether the LinearRing is really closed. if ( isaLinearRing ) { QgsConstWkbPtr checkPtr( sourceWkbPtr ); double x1, y1, x2, y2; checkPtr >> x1 >> y1; checkPtr += skipZM + ( numPoints - 2 ) * ( 2 * sizeof( double ) + skipZM ); checkPtr >> x2 >> y2; isaLinearRing = qgsDoubleNear( x1, x2 ) && qgsDoubleNear( y1, y2 ); } // Process each vertex... if ( simplifyAlgorithm == SnapToGrid ) { double gridOriginX = envelope.xMinimum(); double gridOriginY = envelope.yMinimum(); // Use a factor for the maximum displacement distance for simplification, similar as GeoServer does float gridInverseSizeXY = map2pixelTol != 0 ? ( float )( 1.0f / ( 0.8 * map2pixelTol ) ) : 0.0f; for ( int i = 0; i < numPoints; ++i ) { sourceWkbPtr >> x >> y; sourceWkbPtr += skipZM; if ( i == 0 || !isGeneralizable || !equalSnapToGrid( x, y, lastX, lastY, gridOriginX, gridOriginY, gridInverseSizeXY ) || ( !isaLinearRing && ( i == 1 || i >= numPoints - 2 ) ) ) { targetWkbPtr << x << y; lastX = x; lastY = y; numTargetPoints++; } r.combineExtentWith( x, y ); } }
struct Hjava_lang_String* java_lang_VMRuntime_getLibSuffix(void) { return checkPtr(stringC2Java(LIBRARYSUFFIX)); }
void java_lang_VMSystem_arraycopy0(struct Hjava_lang_Object* src, jint srcpos, struct Hjava_lang_Object* dst, jint dstpos, jint len) { char* in; char* out; int elemsz; Hjava_lang_Class* sclass; Hjava_lang_Class* dclass; sclass = OBJECT_CLASS(src); dclass = OBJECT_CLASS(dst); sclass = Kaffe_get_array_element_type(sclass); dclass = Kaffe_get_array_element_type(dclass); elemsz = TYPE_SIZE(sclass); len *= elemsz; srcpos *= elemsz; dstpos *= elemsz; in = &((char*)ARRAY_DATA(src))[srcpos]; out = &((char*)ARRAY_DATA(dst))[dstpos]; if (sclass == dclass) { #if defined(HAVE_MEMMOVE) memmove((void*)out, (void*)in, (size_t)len); #else /* Do it ourself */ #if defined(HAVE_MEMCPY) if (src != dst) { memcpy((void*)out, (void*)in, (size_t)len); } else #endif if (out < in) { /* Copy forwards */ for (; len > 0; len--) { *out++ = *in++; } } else { /* Copy backwards */ out += len; in += len; for (; len > 0; len--) { *--out = *--in; } } #endif } else { if (CLASS_IS_PRIMITIVE(sclass) || CLASS_IS_PRIMITIVE(dclass)) { Hjava_lang_Throwable* asexc; const char *stype = CLASS_CNAME(sclass); const char *dtype = CLASS_CNAME(dclass); char *b; #define _FORMAT "incompatible array types `%s' and `%s'" b = checkPtr(KMALLOC(strlen(stype)+strlen(dtype)+strlen(_FORMAT))); sprintf(b, _FORMAT, stype, dtype); #undef _FORMAT asexc = ArrayStoreException(b); KFREE(b); throwException(asexc); } for (; len > 0; len -= sizeof(Hjava_lang_Object*)) { Hjava_lang_Object* val = *(Hjava_lang_Object**)in; if (val != 0 && !instanceof(dclass, OBJECT_CLASS(val))) { Hjava_lang_Throwable* asexc; const char *vtype = CLASS_CNAME(OBJECT_CLASS(val)); const char *atype = CLASS_CNAME(dclass); char *b; #define _FORMAT "can't store `%s' in array of type `%s'" b = checkPtr(KMALLOC(strlen(vtype)+strlen(atype)+strlen(_FORMAT))); sprintf(b, _FORMAT, vtype, atype); #undef _FORMAT asexc = ArrayStoreException(b); KFREE(b); throwException(asexc); } *(Hjava_lang_Object**)out = val; in += sizeof(Hjava_lang_Object*); out += sizeof(Hjava_lang_Object*); } } }
/* * Convert string name to class object. */ struct Hjava_lang_Class* java_lang_VMClass_forName0(struct Hjava_lang_String* str, struct Hjava_lang_ClassLoader* loader) { errorInfo einfo; Hjava_lang_Class* clazz; Utf8Const *utf8buf; const char *buf; int jlen; jchar *js; /* * NB: internally, we store class names as path names (with slashes * instead of dots. However, we must also prevent calls to * "java/lang/Object" or "[[Ljava/lang/Object;" from succeeding. * Since class names cannot have slashes, we reject all attempts * to look up names that do. Awkward. Inefficient. */ js = STRING_DATA(str); jlen = STRING_SIZE(str); while (--jlen > 0) { if (*js++ == '/') { postExceptionMessage(&einfo, JAVA_LANG(ClassNotFoundException), "Cannot have slashes - use dots instead."); throwError(&einfo); } } /* * Note the following oddity: * * It is apparently perfectly legal to call forName for array types, * such as "[Ljava.lang.String;" or "[B". * However, it is wrong to call Class.forName("Ljava.lang.String;") * * This situation is similar to the constant pool resolution. We * therefore do the same thing as in getClass in kaffevm/lookup.c, * that is, use either loadArray or loadClass depending on the name. * * This is somewhat described in Section 5.1.3 of the VM * Specification, titled "Array Classes". This section seems to * imply that we must avoid asking a class loader to resolve such * array names (those starting with an [), and this is what calling * loadArray does. */ /* Convert string to utf8, converting '.' to '/' */ utf8buf = checkPtr(stringJava2Utf8ConstReplace(str, '.', '/')); buf = utf8buf->data; if (buf[0] == '[') { clazz = loadArray(utf8buf, loader, &einfo); } else { clazz = loadClass(utf8buf, loader, &einfo); } /* if an error occurred, throw an exception */ if (clazz == 0) { utf8ConstRelease(utf8buf); throwError(&einfo); } utf8ConstRelease(utf8buf); /* * loadClass returns the class in state CSTATE_LINKED. * * Processing to CSTATE_COMPLETE will initialize the class, resolve * its constants and run its static initializers. * * The option to load a class via forName without initializing it * was introduced in 1.2, presumably for the convenience of * programs such as stub compilers. */ if (processClass(clazz, CSTATE_COMPLETE, &einfo) == false) { throwError(&einfo); } return (clazz); }
/* * Convert class to string name. */ struct Hjava_lang_String* java_lang_VMClass_getName(struct Hjava_lang_Class* c) { return(checkPtr(utf8Const2JavaReplace(c->name, '/', '.'))); }