/** * If the suite exists, this function returns a unique identifier of * MIDlet suite. Note that suite may be corrupted even if it exists. * If the suite doesn't exist, a new suite ID is created. * * @param vendor name of the vendor that created the application, as * given in a JAD file * @param name name of the suite, as given in a JAD file * @param pSuiteId [out] receives the platform-specific suite ID of the * application given by vendorName and appName, or string with * a null data if suite does not exist, or * out of memory error occured, or suite is corrupted. * * @return ALL_OK if suite found, * NOT_FOUND if suite does not exist (so a new ID was created), * other error code in case of error */ MIDPError midp_get_suite_id(const pcsl_string* vendor, const pcsl_string* name, SuiteIdType* pSuiteId) { MIDPError status; char *pszError; MidletSuiteData* pData; *pSuiteId = UNUSED_SUITE_ID; /* load _suites.dat */ status = read_suites_data(&pszError); storageFreeError(pszError); if (status != ALL_OK) { return status; } pData = g_pSuitesData; /* try to find a suite */ while (pData != NULL) { if (pcsl_string_equals(&pData->varSuiteData.suiteName, name) && pcsl_string_equals(&pData->varSuiteData.suiteVendor, vendor)) { *pSuiteId = pData->suiteId; return ALL_OK; /* IMPL_NOTE: consider SUITE_CORRUPTED_ERROR */ } pData = pData->nextEntry; } /* suite was not found - create a new suite ID */ status = midp_create_suite_id(pSuiteId); return (status == ALL_OK) ? NOT_FOUND : status; }
/** * Mark of the existing Invocations for a content handler * by suiteId and classname so they can be cleaned up on * exit. * * @param suiteId to match a pending invocation * @param classname to match a pending invocation * @see StoredInvoc * @see #invocQueue */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_midp_content_InvocationStore_setCleanup0(void) { StoredLink* link; StoredInvoc* invoc; SuiteIdType desiredSuiteId; pcsl_string desiredClassname = PCSL_STRING_NULL_INITIALIZER; jboolean cleanup; KNI_StartHandles(1); KNI_DeclareHandle(classname); /* Arg2: non-null classname */ /* Argument indices must match Java native method declaration */ #define markSuiteIdArg 1 #define markClassnameArg 2 #define markCleanup 3 do {/* Block to break out of on exceptions */ if (!isEmpty()) { /* Queue is not empty * Need a string copy of the desired classname * to use for comparisons */ desiredSuiteId = KNI_GetParameterAsInt(markSuiteIdArg); KNI_GetParameterAsObject(markClassnameArg, classname); if (PCSL_STRING_OK != midp_jstring_to_pcsl_string(classname, &desiredClassname)) { KNI_ThrowNew(midpOutOfMemoryError, "InvocationStore_setListenCleanup0 no memory for [desiredClassname]"); break; } cleanup = KNI_GetParameterAsInt(markCleanup); /* Inspect the queue of Invocations and pick one that * matches the suiteId and classname. */ for (link = invocQueue; link != NULL; link = link->flink) { invoc = link->invoc; /* * If the suite matches and the classname matches * set cleanup to the next tid; */ if (desiredSuiteId == invoc->suiteId && pcsl_string_equals(&desiredClassname, &invoc->classname)) { /* Found an entry for the Invocation */ invoc->cleanup = cleanup; invoc->notified = KNI_FALSE; } } } } while (0); pcsl_string_free(&desiredClassname); KNI_EndHandles(); KNI_ReturnVoid(); }
/** * Finds specified string in a string array. * * @param array string array * @param array_len length of array * @param key string to be found * @return 0 if string is not found; */ static int findStringInArray(const pcsl_string *array, int array_len, const pcsl_string *key) { const pcsl_string *current, *last; for (current = array, last = array + array_len; current < last; current++) { if (pcsl_string_equals(current, key)) { return 1; } } return 0; }
/** * Find and return the property the matches the given key. * The returned value need not be freed because it resides * in an internal data structure. * * @param pProperties property list * @param key key of property to find * * @return a pointer to the property value, * or to PCSL_STRING_NULL if not found. */ pcsl_string* midp_find_property(MidpProperties* pProperties, const pcsl_string* key) { int i; /* Properties are stored as key, value pairs. */ for (i = 0; i < pProperties->numberOfProperties; i++) { if (pcsl_string_equals(&pProperties->pStringArr[i * 2], key)) { return &pProperties->pStringArr[(i * 2) + 1]; } } return (pcsl_string*)&PCSL_STRING_NULL; }
/** Finds record store listener by suite ID and record store name */ static RecordStoreListener *findRecordStoreListener( int suiteId, pcsl_string* recordStoreName) { RecordStoreListener *currentPtr; for (currentPtr = rootListenerPtr; currentPtr != NULL; currentPtr = currentPtr->next) { if (currentPtr->suiteId == suiteId && pcsl_string_equals(¤tPtr->recordStoreName, recordStoreName)) { return currentPtr; } } return NULL; }
/* * Search for the node to the linked list * * @param suiteId : ID of the suite * @param name : Name of the record store * * @return the searched node pointer if match exist for suiteId and * recordStoreName * return NULL if node does not exist * */ static lockFileList * findLockById(SuiteIdType suiteId, const pcsl_string * name_str) { lockFileList* currentNodePtr; for (currentNodePtr = lockFileListPtr; currentNodePtr != NULL; currentNodePtr = currentNodePtr->next) { if (currentNodePtr->suiteId == suiteId && pcsl_string_equals(¤tNodePtr->recordStoreName, name_str)) { return currentNodePtr; } } return NULL; }
/** * Function to find a matching entry entry in the queue. * The handlerID must match. The function seeks among new Invocations * (INIT status). * * @param handlerID a string identifying the requested handler * * @return the found invocation, or NULL if no matched invocation. */ StoredInvoc* jsr211_get_invocation(const pcsl_string* handlerID) { StoredLink* curr; /* Inspect the queue of Invocations and pick one that * matches the handlerID. */ for (curr = invocQueue; curr != NULL; curr = curr->flink) { if (pcsl_string_equals(handlerID, &curr->invoc->ID)) { if (curr->invoc->status == STATUS_INIT) { return curr->invoc; } } } return NULL; }
/** * Function to find a matching entry entry in the queue. * The suiteId and classname must match. If the request param * is true then a new Invocation (INIT status) is returned. * If false, then an OK, CANCELLED, INITIATED, or ERROR * status is selected. Other status values are ignored. * * @param suiteId the application suite * @param classname a string identifying the entry point * @param mode one of {@link #MODE_REQUEST}, {@link #MODE_RESPONSE}, * or {@link #MODE_CLEANUP}, {@link #MODE_LREQUEST}, * {@link #MODE_LRESPONSE} * @return a StoredLink if a matching one is found; NULL otherwise */ static StoredLink* invocFind(SuiteIdType suiteId, const pcsl_string* classname, int mode) { StoredLink* curr; StoredInvoc* invoc; /* Inspect the queue of Invocations and pick one that * matches the suiteId and classname. */ for (curr = invocQueue; curr != NULL; ) { invoc = curr->invoc; /* * If the status matches the request * and the suite matches and the classname matches. */ if (modeCheck(invoc, mode) && suiteId == invoc->suiteId && pcsl_string_equals(classname, &invoc->classname)) { if (mode == MODE_CLEANUP) { /* An active or waiting Invocation needs a response */ if ((invoc->status != STATUS_INIT && invoc->status != STATUS_ACTIVE) || (!invoc->responseRequired)) { /* A regular response, discard and continue */ StoredLink* next = curr->flink; removeEntry(curr); invocFree(invoc); curr = next; continue; } } return curr; } curr = curr->flink; } return NULL; }
/** * Parses a value of MIDP_CONTROL_ARGS property from the midlet suite's * JAD file. Syntax of this property is defined by the following grammar: * <pre> * JAD_CONTROL_PARAM = "MIDP_CONTROL_ARGS" EQUAL *( ";" param) * param = report_level_param / log_channels_param / permissions_param / * trace_param / assert_param * report_level_param = "report_level" EQUAL 1*DIGIT * log_channels_param = "log_channels" EQUAL 1*DIGIT *( "," 1*DIGIT) * permissions_param = "allow_all_permissions" * trace_param = "enable_trace" EQUAL bool_val * assert_param = "enable_trace" EQUAL bool_val * bool_val = 0 / 1 * </pre> * * @param pJadProps properties of the midlet suite from its jad file * @param pJadArgs [out] buffer where to store pointers to the name and value of * each control argument * @param maxJadArgs maximal number of arguments that the output buffer can hold */ void parse_control_args_from_jad(const MidpProperties* pJadProps, MIDP_JAD_CONTROL_ARGS* pJadArgs, int maxJadArgs) { int i, currArgNum = 0; int numOfJadProps = pJadProps ? pJadProps->numberOfProperties : 0; /* MIDP_CONTROL_ARGS */ PCSL_DEFINE_STATIC_ASCII_STRING_LITERAL_START(propertyName) { 'M', 'I', 'D', 'P', '_', 'C', 'O', 'N', 'T', 'R', 'O', 'L', '_', 'A', 'R', 'G', 'S', '\0' } PCSL_DEFINE_STATIC_ASCII_STRING_LITERAL_END(propertyName); static jbyte propValue[128]; /* buffer to hold MIDP_ARGS jad property */ for (i = 0; i < (numOfJadProps << 1); i++, i++) { if (pcsl_string_equals(&pJadProps->pStringArr[i], &propertyName)) { const char *pCurr; int propLen = pcsl_string_utf8_length(&pJadProps->pStringArr[i+1]); int start_pos, pos = 0; if (pcsl_string_convert_to_utf8(&pJadProps->pStringArr[i+1], propValue, sizeof(propValue), NULL) != PCSL_STRING_OK) { break; } /* Parse the value of MIDP_CONTROL_ARGS jad property. */ pCurr = (const char*)propValue; while (pos < propLen && currArgNum < maxJadArgs) { /* skip spaces */ if (*pCurr == ' ') { pCurr++; pos++; continue; } pJadArgs[currArgNum].pArgName = pCurr; start_pos = pos; /* look for "=", ";" or end-of-line) */ while (pos < propLen && *pCurr) { if (*pCurr == '=') { pos++; pJadArgs[currArgNum].pArgValue = ++pCurr; break; } else if (*pCurr == ';') { pJadArgs[currArgNum].pArgValue = NULL; break; } pos++; pCurr++; } pJadArgs[currArgNum].argNameLen = pos - start_pos - 1; /* look for the next delimeter (";" or end-of-line) */ while (pos < propLen && *pCurr) { pos++; if (*pCurr++ == ';') { break; } } currArgNum++; } /* end while */ break; } /* end if MIDP_ARGS property found in JAD */ } /* end for each property */ pJadArgs[currArgNum].pArgName = pJadArgs[currArgNum].pArgValue = NULL; pJadArgs[currArgNum].argNameLen = 0; }
/** * Checks if a midlet suite or dynamic component with the given name * created by the given vendor exists. * If it does, this function returns a unique identifier of the suite * or component. Note that the suite or component may be corrupted even * if it exists. If it doesn't, a new suite ID or component ID is created. * * @param type type of the component * @param suiteId if type == COMPONENT_DYNAMIC, contains ID of the suite this * components belongs to; unused otherwise * @param vendor name of the vendor that created the application or component, * as given in a JAD file * @param name name of the suite or component, as given in a JAD file * @param pId [out] receives the platform-specific suite ID or component ID * of the application given by vendor and name, or UNUSED_SUITE_ID / * UNUSED_COMPONENT_ID if suite does not exist, or out of memory * error occured, or the suite / component is corrupted. * * @return ALL_OK if suite or component found, * NOT_FOUND if suite or component does not exist (so a new ID * was created), other error code in case of error */ static MIDPError get_suite_or_component_id(ComponentType type, SuiteIdType suiteId, const pcsl_string* vendor, const pcsl_string* name, jint* pId) { MIDPError status; char *pszError; MidletSuiteData* pData; #if ENABLE_DYNAMIC_COMPONENTS if (type != COMPONENT_DYNAMIC) { *pId = (jint)UNUSED_SUITE_ID; } else { *pId = (jint)UNUSED_COMPONENT_ID; } #else (void)type; (void)suiteId; *pId = (jint)UNUSED_SUITE_ID; #endif /* ENABLE_DYNAMIC_COMPONENTS */ /* load _suites.dat */ status = read_suites_data(&pszError); storageFreeError(pszError); if (status != ALL_OK) { return status; } pData = g_pSuitesData; /* try to find a suite */ while (pData != NULL) { if (pcsl_string_equals(&pData->varSuiteData.suiteName, name) && pcsl_string_equals(&pData->varSuiteData.suiteVendor, vendor) #if ENABLE_DYNAMIC_COMPONENTS && (type == pData->type) && (type != COMPONENT_DYNAMIC || (type == COMPONENT_DYNAMIC && suiteId == pData->suiteId)) #endif ) { #if ENABLE_DYNAMIC_COMPONENTS if (type != COMPONENT_DYNAMIC) { *pId = (jint)pData->suiteId; } else { *pId = (jint)pData->componentId; } #else *pId = (jint)pData->suiteId; #endif /* ENABLE_DYNAMIC_COMPONENTS */ return ALL_OK; /* IMPL_NOTE: consider SUITE_CORRUPTED_ERROR */ } pData = pData->nextEntry; } /* suite or component was not found - create a new suite or component ID */ #if ENABLE_DYNAMIC_COMPONENTS if (type != COMPONENT_DYNAMIC) { status = midp_create_suite_id((SuiteIdType*)pId); } else { status = midp_create_component_id((ComponentIdType*)pId); } #else status = midp_create_suite_id((SuiteIdType*)pId); #endif /* ENABLE_DYNAMIC_COMPONENTS */ return (status == ALL_OK) ? NOT_FOUND : status; }
/** * * Resets the request or response flags for listener notification. * Each request or response is marked as not having been notified. * * @param suiteId to match a pending invocation * @param classname to match a pending invocation * @param mode one of {@link #MODE_LREQUEST}, {@link #MODE_LRESPONSE} */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_midp_content_InvocationStore_setListenNotify0(void) { StoredLink* link; StoredInvoc* invoc; SuiteIdType desiredSuiteId; pcsl_string desiredClassname = PCSL_STRING_NULL_INITIALIZER; KNI_StartHandles(2); KNI_DeclareHandle(classname); /* Arg2: non-null classname */ int mode; /* Arg3: requested invocation mode */ /* Argument indices must match Java native method declaration */ #define listenSuiteIdArg 1 #define listenClassnameArg 2 #define listenModeArg 3 do {/* Block to break out of on exceptions */ if (!isEmpty()) { /* Queue is not empty * Need a string copy of the desired suiteId and classname * to use for comparisons */ desiredSuiteId = KNI_GetParameterAsInt(listenSuiteIdArg); KNI_GetParameterAsObject(listenClassnameArg, classname); if (PCSL_STRING_OK != midp_jstring_to_pcsl_string(classname, &desiredClassname)) { KNI_ThrowNew(midpOutOfMemoryError, "InvocationStore_setListenNotify0 no memory for [desiredClassname]"); break; } /* Get the desired request mode. */ mode = KNI_GetParameterAsInt(listenModeArg); /* Inspect the queue of Invocations and pick one that * matches the suiteId and classname */ for (link = invocQueue; link != NULL; link = link->flink) { invoc = link->invoc; /* * If the status matches the request * and the suite matches and the classname matches. */ if (mode == MODE_LREQUEST && invoc->status == STATUS_INIT) { /* This invocation is a match; check classname and suite below */ } else if (mode == MODE_LRESPONSE && (invoc->status >= STATUS_OK && invoc->status <= STATUS_INITIATED)) { /* A pending response; check classname and suite below */ } else { /* Not this invocation; on to the next */ continue; } /* Check if this is the right class and suite */ if (desiredSuiteId == invoc->suiteId && pcsl_string_equals(&desiredClassname, &invoc->classname)) { /* Reset the flag so this Invocation will notify. */ invoc->notified = KNI_FALSE; } } } } while (KNI_FALSE); /* TBD: MidpMalloc failure not reported; not found is returned */ /* Always free strings allocated */ pcsl_string_free(&desiredClassname); KNI_EndHandles(); KNI_ReturnVoid(); }
/** * Compares JAD and Manifest file properties that MUST be the same. * The properties are: * <B>MIDlet-Name</B> * <B>MIDlet-Vendor</B> * <B>MIDlet-Version</B> * * @param jadsmp MidpProperties struct that contains parsed JAD properties. * @param mfsmp MidpProperties struct that contains parsed Manifest properties. * @return On success: ALL_OK * On mismatch: * SUITE_NAME_PROP_NOT_MATCH * SUITE_VENDOR_PROP_NOT_MATCH * SUITE_VERSION_PROP_NOT_MATCH * On missing property: * NO_SUITE_NAME_PROP * NO_SUITE_VENDOR_PROP * NO_SUITE_VERSION_PROP */ int compareJADandManifestProperties(MidpProperties* jadsmp, MidpProperties* mfsmp) { /* three properties MUST be similar in jad and manifest */ const pcsl_string* jad_name = &PCSL_STRING_NULL; const pcsl_string* jad_version = &PCSL_STRING_NULL; const pcsl_string* jad_vendor = &PCSL_STRING_NULL; const pcsl_string* mf_name = &PCSL_STRING_NULL; const pcsl_string* mf_version = &PCSL_STRING_NULL; const pcsl_string* mf_vendor = &PCSL_STRING_NULL; /* compare jad and manifest properties */ jad_name = midp_find_property(jadsmp, &SUITE_NAME_PROP); if (pcsl_string_is_null(jad_name)) { REPORT_ERROR(LC_AMS, "Can't get SUITE_NAME_PROP from JAD. This should not happen at this stage!"); return NO_SUITE_NAME_PROP; } mf_name = midp_find_property(mfsmp, &SUITE_NAME_PROP); if (pcsl_string_is_null(mf_name)) { REPORT_ERROR(LC_AMS, "Can't get SUITE_NAME_PROP from Manifest. This should not happen at this stage!"); return NO_SUITE_NAME_PROP; /* handle it some how */ } if ( ! pcsl_string_equals(jad_name, mf_name)) { /* versions are not equal */ REPORT_ERROR(LC_AMS, "Manifest and Jad names are not equal."); return SUITE_NAME_PROP_NOT_MATCH; } jad_vendor = midp_find_property(jadsmp, &SUITE_VENDOR_PROP); if (pcsl_string_is_null(jad_vendor)) { REPORT_ERROR(LC_AMS, "Can't get SUITE_VENDOR_PROP from JAD. This should not happen at this stage!\n"); return NO_SUITE_VENDOR_PROP; } mf_vendor = midp_find_property(mfsmp, &SUITE_VENDOR_PROP); if (pcsl_string_is_null(mf_vendor)) { REPORT_ERROR(LC_AMS, "Can't get SUITE_VENDOR_PROP from Manifest. This should not happen at this stage!"); return NO_SUITE_VENDOR_PROP; } if ( ! pcsl_string_equals(jad_vendor, mf_vendor)) { /* versions are not equal */ REPORT_ERROR(LC_AMS, "Manifest and Jad vendors are not equal."); return SUITE_VENDOR_PROP_NOT_MATCH; } jad_version = midp_find_property(jadsmp, &SUITE_VERSION_PROP); if (pcsl_string_is_null(jad_version)) { REPORT_ERROR(LC_AMS, "Can't get SUITE_VERSION_PROP from JAD. This should not happen at this stage!"); return NO_SUITE_VERSION_PROP; } mf_version = midp_find_property(mfsmp, &SUITE_VERSION_PROP); if (pcsl_string_is_null(mf_version)) { REPORT_ERROR(LC_AMS, "Can't get SUITE_VERSION_PROP from Manifest. This should not happen at this stage!"); return NO_SUITE_VERSION_PROP; } { if (0 != midpCompareVersion(jad_version, mf_version)) { /* versions are not equal */ REPORT_ERROR(LC_AMS, "Manifest and Jad versions are not equal."); return SUITE_VERSION_PROP_NOT_MATCH; } } return ALL_OK; } /* end of compareJADandManifestProperties */