/** * Loads the handler's data field. Allowed fields are: <UL> * <LI> JSR211_FIELD_TYPES, <LI> JSR211_FIELD_SUFFIXES, * <LI> JSR211_FIELD_ACTIONS, <LI> JSR211_FIELD_LOCALES, * <LI> JSR211_FIELD_ACTION_MAP, <LI> and JSR211_FIELD_ACCESSES. </UL> * * @param id requested handler ID. * @param field_id requested field. * @param result output structure where requested array is placed to. * <br>Use @link jsr211_fillStringArray function to fill this structure. * @return status of the operation */ jsr211_result jsr211_get_handler_field(const pcsl_string* id, jsr211_field field_id, /*OUT*/ JSR211_RESULT_STRARRAY* result) { int result_len = 0; pcsl_string* buf = NULL; if (record_struct[CHR_INDEX((int)(field_id))] != field_array) { return JSR211_FAILED; } if (open_table_file(0) != JSR211_OK) { return JSR211_FAILED; } if (find_next_by_field(NULL, JSR211_FIELD_ID, id, JSR211_TRUE, find_exact) == -1) { close_table_file(); return JSR211_FAILED; } /* reading field */ position_field(CHR_INDEX((int)(field_id))); read_string_array(&result_len, &buf); if (result_len > 0) { jsr211_fillStringArray(buf, result_len, result); free_pcsl_string_list(buf, result_len); } close_table_file(); return JSR211_OK; }
/** * Fetch a KNI String array object into the string array. * * @param arrObj KNI Java String object handle * @param arrPtr the String array pointer for values storing * @return number of retrieved strings * <BR>KNI_ENOMEM - indicates memory allocation error */ static int getStringArray(jobjectArray arrObj, pcsl_string** arrPtr) { int i, n = 0; pcsl_string* arr; KNI_StartHandles(1); KNI_DeclareHandle(strObj); n = KNI_IsNullHandle(arrObj)? 0: (int)KNI_GetArrayLength(arrObj); while (n > 0) { arr = alloc_pcsl_string_list(n); if (arr == NULL) { n = KNI_ENOMEM; break; } *arrPtr = arr; for (i = 0; i < n; i++, arr++) { KNI_GetObjectArrayElement(arrObj, i, strObj); if (PCSL_STRING_OK != midp_jstring_to_pcsl_string(strObj, arr)) { free_pcsl_string_list(*arrPtr, n); *arrPtr = NULL; n = KNI_ENOMEM; break; } } break; } KNI_EndHandles(); return n; }
/** * Free a list of properties. Does nothing if passed NULL. * * @param pProperties property list */ void midp_free_properties(MidpProperties* pProperties) { /* Properties are stored as key, value pairs. */ if (!pProperties || pProperties->numberOfProperties <= 0) { return; } free_pcsl_string_list(pProperties->pStringArr, pProperties->numberOfProperties * 2); pProperties->pStringArr = NULL; }
/** * Cleans up all data memebers of given data structure, * <br>but <code>handler</code> itself is not cleared. * @param handler pointer on data structure * <code>JSR211_content_handler</code> to be cleared. */ void jsr211_cleanHandlerData(JSR211_content_handler *handler) { // clean up handler structure if (pcsl_string_is_null(&(handler->id)) == PCSL_FALSE) { pcsl_string_free(&(handler->id)); } if (pcsl_string_is_null(&(handler->class_name)) == PCSL_FALSE) { pcsl_string_free(&(handler->class_name)); } if (handler->type_num > 0 && handler->types != NULL) { free_pcsl_string_list(handler->types, handler->type_num); } if (handler->suff_num > 0 && handler->suffixes != NULL) { free_pcsl_string_list(handler->suffixes, handler->suff_num); } if (handler->act_num > 0 && handler->actions != NULL) { free_pcsl_string_list(handler->actions, handler->act_num); } if (handler->locale_num > 0 && handler->locales != NULL) { free_pcsl_string_list(handler->locales, handler->locale_num); } if (handler->act_num > 0 && handler->locale_num > 0 && handler->action_map != NULL) { free_pcsl_string_list(handler->action_map, handler->act_num * handler->locale_num); } if (handler->access_num > 0 && handler->accesses != NULL) { free_pcsl_string_list(handler->accesses, handler->access_num); } }
/** * Remove all the Record Stores for a suite. * * @param filenameBase filenameBase of the suite * @param id ID of the suite * Only one of the parameters will be used by a given implementation. In the * case where the implementation might store data outside of the MIDlet storage, * the filenameBase will be ignored and only the suite id will be pertinent. * * @return false if out of memory else true */ int rmsdb_remove_record_stores_for_suite(pcsl_string* filenameBase, SuiteIdType id) { int numberOfNames; pcsl_string* pNames; int i; int result = 1; char* pszError; (void)id; /* avoid a compiler warning */ /* * This is a public API which can be called without the VM running * so we need automatically init anything needed, to make the * caller's code less complex. * * Initialization is performed in steps so that we do use any * extra resources such as the VM for the operation being performed. */ if (midpInit(LIST_LEVEL) != 0) { return 0; } numberOfNames = rmsdb_get_record_store_list(filenameBase, &pNames); if (numberOfNames == OUT_OF_MEM_LEN) { return 0; } if (numberOfNames <= 0) { return 1; } for (i = 0; i < numberOfNames; i++) { if (rmsdb_record_store_delete(&pszError, filenameBase, &pNames[i], DB_EXTENSION_INDEX) <= 0) { result = 0; break; } if (rmsdb_record_store_delete(&pszError, filenameBase, &pNames[i], IDX_EXTENSION_INDEX) <= 0) { /* * Since index file is optional, ignore error here. * result = 0; break; */ } } recordStoreFreeError(pszError); free_pcsl_string_list(pNames, numberOfNames); return result; }
/** * Gets the amount of RMS storage on the device that this suite is using. * * @param filenameBase filenameBase of the suite * @param id ID of the suite * Only one of the parameters will be used by a given implementation. In the * case where the implementation might store data outside of the MIDlet storage, * the filenameBase will be ignored and only the suite id will be pertinent. * * @return number of bytes of storage the suite is using or OUT_OF_MEM_LEN */ long rmsdb_get_rms_storage_size(pcsl_string* filenameBase, SuiteIdType id) { int numberOfNames; pcsl_string* pNames; int i; int used = 0; int handle; char* pszError; char* pszTemp; (void)id; /* avoid a compiler warning */ numberOfNames = rmsdb_get_record_store_list(filenameBase, &pNames); if (numberOfNames == OUT_OF_MEM_LEN) { return OUT_OF_MEM_LEN; } if (numberOfNames == 0) { return 0; } for (i = 0; i < numberOfNames; i++) { handle = rmsdb_record_store_open(&pszError, filenameBase, &pNames[i], DB_EXTENSION_INDEX); if (pszError != NULL) { recordStoreFreeError(pszError); break; } if (handle == -1) { break; } used += recordStoreSizeOf(&pszError, handle); recordStoreFreeError(pszError); recordStoreClose(&pszTemp, handle); recordStoreFreeError(pszTemp); if (pszError != NULL) { break; } } free_pcsl_string_list(pNames, numberOfNames); return used; }
/** * Loads the properties of a MIDlet suite from persistent storage. * * @param suiteId ID of the suite * @param pJadProps [out] pointer to a structure containing an array of strings, * in a pair pattern of key and value; NULL may be passed if it is not required * to read JAD properties * @param pJarProps [out] pointer to a structure containing an array of strings, * in a pair pattern of key and value; NULL may be passed if it is not required * to read JAR properties * * @return error code (ALL_OK for success) */ MIDPError load_install_properties(SuiteIdType suiteId, MidpProperties* pJadProps, MidpProperties* pJarProps) { pcsl_string filename; char* pszError = NULL; int handle, i, n; int numberOfProps; MIDPError status; status = get_property_file(suiteId, KNI_TRUE, &filename); if (status != ALL_OK) { return status; } handle = storage_open(&pszError, &filename, OPEN_READ); pcsl_string_free(&filename); if (pszError != NULL) { storageFreeError(pszError); return IO_ERROR; } status = ALL_OK; /* Read JAD, then JAR properties. */ for (n = 0; n < 2; n++) { MidpProperties *pProps = n ? pJarProps : pJadProps; if (!pProps) { continue; } storageRead(&pszError, handle, (char*)&numberOfProps, sizeof (numberOfProps)); if (pszError != NULL) { break; } pProps->pStringArr = alloc_pcsl_string_list(numberOfProps << 1); for (i = 0; i < numberOfProps << 1; i++) { storage_read_utf16_string(&pszError, handle, &pProps->pStringArr[i]); if (pszError != NULL) { break; } } if (pszError != NULL) { break; } pProps->numberOfProperties = numberOfProps; } if (pszError != NULL) { status = IO_ERROR; storageFreeError(pszError); } storageClose(&pszError, handle); storageFreeError(pszError); if (status != ALL_OK) { if (pJadProps) { free_pcsl_string_list(pJadProps->pStringArr, pJadProps->numberOfProperties << 1); } if (pJarProps) { free_pcsl_string_list(pJarProps->pStringArr, pJarProps->numberOfProperties << 1); } } return status; }
/** * Retrieves the list of strings in a file. * The file has the number of strings at the front, each string * is a length and the jchars. * * @param ppszError pointer to character string pointer to accept an error * @param pFilename name of the file of strings * @param paList pointer to an array of pcsl_strings, free with * free_pcsl_string_list * @param pStringNum number of strings if successful (can be 0) * * @return error code (ALL_OK if successful) */ static MIDPError get_string_list(char** ppszError, const pcsl_string* pFilename, pcsl_string** paList, int* pStringNum) { char* pszTemp; int i = 0; int handle; int numberOfStrings = 0; pcsl_string* pStrings = NULL; MIDPError status = ALL_OK; *ppszError = NULL; *paList = NULL; *pStringNum = 0; handle = storage_open(ppszError, pFilename, OPEN_READ); if (*ppszError != NULL) { return IO_ERROR; } do { storageRead(ppszError, handle, (char*)&numberOfStrings, sizeof (numberOfStrings)); if (*ppszError != NULL) { status = IO_ERROR; break; } if (numberOfStrings == 0) { break; } pStrings = alloc_pcsl_string_list(numberOfStrings); if (pStrings == NULL) { status = OUT_OF_MEMORY; break; } for (i = 0; i < numberOfStrings; i++) { pStrings[i] = PCSL_STRING_NULL; } for (i = 0; i < numberOfStrings; i++) { storage_read_utf16_string(ppszError, handle, &pStrings[i]); if (*ppszError != NULL) { status = IO_ERROR; break; } } if (i != numberOfStrings) { status = SUITE_CORRUPTED_ERROR; break; } } while (0); storageClose(&pszTemp, handle); storageFreeError(pszTemp); if (status == ALL_OK) { *paList = pStrings; *pStringNum = numberOfStrings; } else if (pStrings != NULL) { free_pcsl_string_list(pStrings, i); } return status; }
/** * Returns an array of the names of record stores owned by the * MIDlet suite. * * @param filenameBase filenameBase of the suite * @param ppNames pointer to pointer that will be filled in with names * * @return number of record store names or OUT_OF_MEM_LEN */ int rmsdb_get_record_store_list(pcsl_string* filenameBase, pcsl_string* *const ppNames) { int numberOfStores; pcsl_string root; pcsl_string* pStores; pcsl_string filename; pcsl_string ascii_name = PCSL_STRING_NULL_INITIALIZER; int i; void* handle = NULL; MIDPError status; int f_errc; pcsl_string_status s_errc; /* IMPL_NOTE: how can we get it statically? */ const int dbext_len = pcsl_string_length(&DB_EXTENSION); *ppNames = NULL; /* * IMPL_NOTE: for security reasons the record store is always * located in the internal storage. */ status = buildSuiteFilename(filenameBase, &PCSL_STRING_EMPTY, -1, &root); if (status != MIDP_ERROR_NONE) { return status; } if (pcsl_string_is_null(&root)) { return 0; } numberOfStores = rmsdb_get_number_of_record_stores_int(&root); if (numberOfStores <= 0) { pcsl_string_free(&root); return numberOfStores; } pStores = alloc_pcsl_string_list(numberOfStores); if (pStores == NULL) { pcsl_string_free(&root); return OUT_OF_MEM_LEN; } handle = storage_open_file_iterator(&root); if (!handle) { pcsl_string_free(&root); return OUT_OF_MEM_LEN; } /* the main loop */ for (i=0,f_errc=0,s_errc=0;;) { f_errc = storage_get_next_file_in_iterator(&root, handle, &filename); if (0 != f_errc) { f_errc = 0; break; } if (pcsl_string_ends_with(&filename, &DB_EXTENSION)) { s_errc = pcsl_string_substring(&filename, pcsl_string_length(&root), pcsl_string_length(&filename) - dbext_len, &ascii_name); pcsl_string_free(&filename); if (PCSL_STRING_OK != s_errc ) { break; } s_errc = pcsl_esc_extract_attached(0, &ascii_name, &pStores[i]); pcsl_string_free(&ascii_name); if (PCSL_STRING_OK != s_errc ) { break; } i++; } pcsl_string_free(&filename); /* IMPL_NOTE: do we need this one? isn't it useless? */ if (i == numberOfStores) { break; } } pcsl_string_free(&root); storageCloseFileIterator(handle); if (f_errc || s_errc) { /* The loop stopped because we ran out of memory. */ free_pcsl_string_list(pStores, i); return OUT_OF_MEM_LEN; } *ppNames = pStores; return numberOfStores; }
/** * Returns all found values for specified field. Tha allowed fields are: <ul> * <li> JSR211_FIELD_ID, <li> JSR211_FIELD_TYPES, <li> JSR211_FIELD_SUFFIXES, * <li> and JSR211_FIELD_ACTIONS. </ul> * Values should be selected only from handlers accessible for given caller_id. * * @param caller_id calling application identifier. * @param field search field id * @param result output structure where result is placed to. * <br>Use @link jsr211_fillStringArray function to fill this structure. * @return status of the operation */ jsr211_result jsr211_get_all(const pcsl_string* caller_id, jsr211_field field, /*OUT*/ JSR211_RESULT_STRARRAY* result) { long current_position; int found_num, access, current_size; pcsl_string *res_buffer = NULL; pcsl_string *current_result, *last; int chr = CHR_INDEX((int)(field)); int isString; switch (record_struct[chr]) { case field_string: isString = 1; break; case field_array: isString = 0; break; default: return JSR211_FAILED; } if (open_table_file(0) != JSR211_OK) { return JSR211_FAILED; } res_buffer = alloc_pcsl_string_list(JSR211_MAX_RESULT_SET); if (res_buffer == NULL) { close_table_file(); return JSR211_FAILED; } current_position = 0; for (current_result = res_buffer, last = res_buffer + JSR211_MAX_RESULT_SET; current_result < last;) { access = check_access(caller_id, current_position, ¤t_size); if (access == -1) { break; } if (access && position_field(chr) > 0) { if (isString) { read_string(current_result); if (!findStringInArray(res_buffer, current_result - res_buffer, current_result)) { current_result++; } } else { pcsl_string *array_res = NULL, *results, *last_res; int array_length = 0; read_string_array(&array_length, &array_res); if (array_length > 0) { for (results = array_res, last_res = array_res + array_length; results < last_res && current_result < last; results++) { if (!findStringInArray(res_buffer, current_result - res_buffer, results)) { *(current_result++) = *results; *results = PCSL_STRING_NULL; } } free_pcsl_string_list(array_res, array_length); } } } storagePosition(&io_error_message, table_file, current_position); current_position += current_size; goto_next_record(); } if ((found_num = (int)(current_result - res_buffer))) { jsr211_fillStringArray(res_buffer, found_num, result); } free_pcsl_string_list(res_buffer, JSR211_MAX_RESULT_SET); close_table_file(); return JSR211_OK; }
/** * Returns an array of the names of record stores owned by the * MIDlet suite. * * @param suiteId * @param ppNames pointer to pointer that will be filled in with names * * @return number of record store names or OUT_OF_MEM_LEN */ int rmsdb_get_record_store_list(SuiteIdType suiteId, pcsl_string* *const ppNames) { int numberOfStores; pcsl_string root; pcsl_string* pStores; pcsl_string filename; pcsl_string ascii_name = PCSL_STRING_NULL_INITIALIZER; int i; void* handle = NULL; MIDPError status; int f_errc; pcsl_string_status s_errc; StorageIdType storageId; /* IMPL_NOTE: how can we get it statically? */ const int dbext_len = pcsl_string_length(&DB_EXTENSION); *ppNames = NULL; /* * IMPL Note: here is assumed that the record store is located in the same * storage as the midlet suite. This may not be true. */ status = midp_suite_get_suite_storage(suiteId, &storageId); if (status != ALL_OK) { return OUT_OF_MEM_LEN; } status = midp_suite_get_rms_filename(suiteId, storageId, -1, &PCSL_STRING_EMPTY, &root); if (status != ALL_OK) { return OUT_OF_MEM_LEN; } if (pcsl_string_is_null(&root)) { return 0; } numberOfStores = rmsdb_get_number_of_record_stores_int(&root); if (numberOfStores <= 0) { pcsl_string_free(&root); return numberOfStores; } pStores = alloc_pcsl_string_list(numberOfStores); if (pStores == NULL) { pcsl_string_free(&root); return OUT_OF_MEM_LEN; } handle = storage_open_file_iterator(&root); if (!handle) { pcsl_string_free(&root); return OUT_OF_MEM_LEN; } /* the main loop */ for(i=0,f_errc=0,s_errc=0;;) { f_errc = storage_get_next_file_in_iterator(&root, handle, &filename); if (0 != f_errc) { f_errc = 0; break; } if (pcsl_string_ends_with(&filename, &DB_EXTENSION)) { s_errc = pcsl_string_substring(&filename, pcsl_string_length(&root), pcsl_string_length(&filename) - dbext_len, &ascii_name); pcsl_string_free(&filename); if (PCSL_STRING_OK != s_errc ) { break; } s_errc = escaped_ascii_to_unicode(&ascii_name, &pStores[i]); pcsl_string_free(&ascii_name); if (PCSL_STRING_OK != s_errc ) { break; } i++; } pcsl_string_free(&filename); /* IMPL_NOTE: do we need this one? isn't it useless? */ if (i == numberOfStores) { break; } } pcsl_string_free(&root); storageCloseFileIterator(handle); if (f_errc || s_errc) { /* The loop stopped because we ran out of memory. */ free_pcsl_string_list(pStores, i); return OUT_OF_MEM_LEN; } *ppNames = pStores; return numberOfStores; }