📄 rms.c
字号:
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;}/** * Returns true if the suite has created at least one record store. * * @param filenameBase filenameBase of the suite * * @return true if the suite has at least one record store */intrmsdb_suite_has_rms_data(pcsl_string* filenameBase) { /* * 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; } return (rmsdb_get_number_of_record_stores(filenameBase) > 0);}/** * Approximation of remaining RMS space in storage for a suite. * * Usage Warning: This may be a slow operation if * the platform has to look at the size of each file * stored in the MIDP memory space and include its size * in the total. * * @param storageId storage id of the suite * * @return the approximate space available to grow the * record store in bytes. */longrmsdb_get_new_record_store_space_available(int storageId) { return rmsdb_get_record_store_space_available(-1, storageId);}/** * Open a native record store file. * * @param ppszError where to put an I/O error * @param filenameBase filenameBase of the MIDlet suite that owns the record * store * @param name name of the record store * @param extension extension number to add to the end of the file name * * @return storage handle on success * return -1 if there is an error getting the filename * return -2 if the file is locked */intrmsdb_record_store_open(char** ppszError, pcsl_string* filenameBase, const pcsl_string * name_str, int extension) { pcsl_string filename_str; int handle;#if ENABLE_RECORDSTORE_FILE_LOCK lockFileList* searchedNodePtr = NULL;#endif *ppszError = NULL;#if ENABLE_RECORDSTORE_FILE_LOCK if (extension == DB_EXTENSION_INDEX) { searchedNodePtr = rmsdb_find_file_lock_by_id(filenameBase, name_str); if (searchedNodePtr != NULL) { /* File is already opened by another isolate, return an error */ *ppszError = (char *)FILE_LOCK_ERROR; return -2; } }#endif /* * IMPL_NOTE: for security reasons the record store is always * located in the internal storage. */ if (MIDP_ERROR_NONE != rmsdb_get_unique_id_path(filenameBase, INTERNAL_STORAGE_ID, name_str, extension, &filename_str)) { return -1; } handle = midp_file_cache_open(ppszError, INTERNAL_STORAGE_ID, &filename_str, OPEN_READ_WRITE); pcsl_string_free(&filename_str); if (*ppszError != NULL) { return -1; }#if ENABLE_RECORDSTORE_FILE_LOCK if (extension == DB_EXTENSION_INDEX) { if (rmsdb_create_file_lock(filenameBase, name_str, handle) != 0) { return -1; } }#endif return handle;}/** * Approximation of remaining RMS space in storage for a suite. * * Usage Warning: This may be a slow operation if * the platform has to look at the size of each file * stored in the MIDP memory space and include its size * in the total. * * @param handle handle to record store storage * @param pStorageId storage id of the suite * * @return the approximate space available to grow the * record store in bytes. */longrmsdb_get_record_store_space_available(int handle, int pStorageId) { /* Storage may have more then 2Gb space available so use 64-bit type */ jlong availSpace; long availSpaceUpTo2Gb; char* pszError; StorageIdType storageId; /* * IMPL_NOTE: for security reasons we introduce a limitation that the * suite's RMS must be located at the internal storage. * Note that the public RecordStore API doesn't support * a storageId parameter. * There is a plan to get rid of such limitation by introducing a * function that will return a storage ID by the suite ID and RMS name. */ storageId = pStorageId; availSpace = midp_file_cache_available_space(&pszError, handle, storageId); /* * Public RecordStore API uses Java int type for the available space * so here we trim the real space to 2Gb limit. */ availSpaceUpTo2Gb = (availSpace <= LONG_MAX) ? availSpace : LONG_MAX; return availSpaceUpTo2Gb;}/** * Change the read/write position of an open file in storage. * The position is a number of bytes from beginning of the file. * Does not block. * * If not successful *ppszError will set to point to an error string, * on success it will be set to NULL. * * @param ppszError where to put an I/O error * @param handle handle to record store storage * @param pos position within the file to move the current_pos * pointer to. */void recordStoreSetPosition(char** ppszError, int handle, int pos) { midp_file_cache_seek(ppszError, handle, pos);}/** * Write to an open file in storage. Will write all of the bytes in the * buffer or pass back an error. Does not block. * * If not successful *ppszError will set to point to an error string, * on success it will be set to NULL. * * @param ppszError where to put an I/O error * @param handle handle to record store storage * @param buffer buffer to read out of. * @param length the number of bytes to write. */voidrecordStoreWrite(char** ppszError, int handle, char* buffer, long length) { midp_file_cache_write(ppszError, handle, buffer, length);}/** * Commit pending writes * * If not successful *ppszError will set to point to an error string, * on success it will be set to NULL. * * @param ppszError where to put an I/O error * @param handle handle to record store storage */voidrecordStoreCommitWrite(char** ppszError, int handle) { midp_file_cache_flush(ppszError, handle);}/** * Read from an open file in storage, returning the number of bytes read or * -1 for the end of the file. May read less than the length of the buffer. * Does not block. * * If not successful *ppszError will set to point to an error string, * on success it will be set to NULL. * * @param ppszError where to put an I/O error * @param handle handle to record store storage * @param buffer buffer to read in to. * @param length the number of bytes to read. * * @return the number of bytes read. */longrecordStoreRead(char** ppszError, int handle, char* buffer, long length) { return midp_file_cache_read(ppszError, handle, buffer, length);}/** * Close a storage object opened by rmsdb_record_store_open. Does no block. * * If not successful *ppszError will set to point to an error string, * on success it will be set to NULL. * * @param ppszError where to put an I/O error * @param handle handle to record store storage * */voidrecordStoreClose(char** ppszError, int handle) { midp_file_cache_close(ppszError, handle); /* * Verify that there is no error in closing the file. In case of any errors * there is no need to remove the node from the linked list */ if (*ppszError != NULL) { return; }#if ENABLE_RECORDSTORE_FILE_LOCK /* * Search the node based on handle. Delete the node upon file close */ rmsdb_delete_file_lock(handle);#endif }/* * Truncate the size of an open file in storage. Does not block. * * If not successful *ppszError will set to point to an error string, * on success it will be set to NULL. * * @param ppszError where to put an I/O error * @param handle handle to record store storage * @param size new size of the file */voidrecordStoreTruncate(char** ppszError, int handle, long size) { midp_file_cache_truncate(ppszError, handle, size);}/* * Free the error string returned from a record store function. * Does nothing if a NULL is passed in. * This allows for systems that provide error messages that are allocated * dynamically. * * @param pszError an I/O error */voidrecordStoreFreeError(char* pszError) { if (pszError != FILE_LOCK_ERROR) { storageFreeError(pszError); }}/* * Return the size of an open record store. Does not block. * * If not successful *ppszError will set to point to an error string, * on success it will be set to NULL. */longrecordStoreSizeOf(char** ppszError, int handle) { return midp_file_cache_sizeof(ppszError, handle);}/** * 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 */longrmsdb_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;}/* Utility function to build filename from filename base, name and extension * * @param filenameBase base for the filename * @param name name of record store * @param extension rms extension that can be MIDP_RMS_DB_EXT or * MIDP_RMS_IDX_EXT * * @return the filename */static MIDPError buildSuiteFilename(pcsl_string* filenameBase, const pcsl_string* name, jint extension, pcsl_string* pFileName) { pcsl_string returnPath = PCSL_STRING_NULL; pcsl_string rmsFileName = PCSL_STRING_NULL; jsize filenameBaseLen = pcsl_string_length(filenameBase); jsize nameLen = pcsl_string_length(name); *pFileName = PCSL_STRING_NULL; if (nameLen > 0) { const pcsl_string* ext; jsize extLen; int fileNameLen; if (MIDP_RMS_IDX_EXT == extension) { ext = &IDX_EXTENSION; extLen = pcsl_string_length(&IDX_EXTENSION); } else if (MIDP_RMS_DB_EXT == extension) { ext = &DB_EXTENSION; extLen = pcsl_string_length(&DB_EXTENSION); } else { return BAD_PARAMS; } /* performance hint: predict buffer capacity */ fileNameLen = PCSL_STRING_ESCAPED_BUFFER_SIZE(nameLen + extLen); pcsl_string_predict_size(&rmsFileName, fileNameLen); if (pcsl_esc_attach_string(name, &rmsFileName) != PCSL_STRING_OK || pcsl_string_append(&rmsFileName, ext) != PCSL_STRING_OK) { pcsl_string_free(&rmsFileName); return OUT_OF_MEMORY; } } /* performance hint: predict buffer capacity */ pcsl_string_predict_size(&returnPath, filenameBaseLen + pcsl_string_length(&rmsFileName)); if (PCSL_STRING_OK != pcsl_string_append(&returnPath, filenameBase) || PCSL_STRING_OK != pcsl_string_append(&returnPath, &rmsFileName)) { pcsl_string_free(&rmsFileName); pcsl_string_free(&returnPath); return OUT_OF_MEMORY; } pcsl_string_free(&rmsFileName); *pFileName = returnPath; return ALL_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -