⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rms.c

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */#include "kni.h"#include "midp_file_cache.h"#include <midpStorage.h>#include <midpMalloc.h>#include <midpInit.h>#include <midpRMS.h>#include <midpUtilKni.h>#include <suitestore_rms.h>#include <limits.h> /* for LONG_MAX */#include <pcsl_esc.h>#include <pcsl_string.h>#if ENABLE_RECORDSTORE_FILE_LOCK#include "rms_file_lock.h"#endif/** Easily recognize record store files in the file system */static const int DB_EXTENSION_INDEX = 0;static const int IDX_EXTENSION_INDEX = 1;/*PCSL_DEFINE_STATIC_ASCII_STRING_LITERAL_START( DB_EXTENSION )    {'.', 'd', 'b', '\0'}PCSL_DEFINE_STATIC_ASCII_STRING_LITERAL_END( DB_EXTENSION );PCSL_DEFINE_STATIC_ASCII_STRING_LITERAL_START( IDX_EXTENSION )    {'.', 'i', 'd', 'x', '\0'}PCSL_DEFINE_STATIC_ASCII_STRING_LITERAL_END( IDX_EXTENSION );*/static const char* const FILE_LOCK_ERROR = "File is locked, can not open";/* Forward declarations for local functions */static MIDPError buildSuiteFilename(pcsl_string * filenameBase,                                    const pcsl_string* name, jint extension,                                     pcsl_string * pFileName);/** * Returns a storage system unique string for this record store file * based on the current vendor and suite of the running MIDlet. * <ul> *  <li>The native storage path for the desired MIDlet suite *  is acquired from the Scheduler. * *  <li>The <code>filename</code> arg is converted into an ascii *  equivalent safe to use directly in the underlying *  file system and appended to the native storage path.  See the *  com.sun.midp.io.j2me.storage.File.unicodeToAsciiFilename() *  method for conversion details. * *  <li>Finally the extension number given by the extension parameter *  is appended to the file name. * <ul> * @param filenameBase filename base of the MIDlet suite that owns the record  * store * @param storageId ID of the storage where the RMS will be located * @param name name of the record store * @param extension extension number to add to the end of the file name * * @return a unique identifier for this record store file */static MIDP_ERRORrmsdb_get_unique_id_path(pcsl_string* filenameBase, StorageIdType storageId,                         const pcsl_string* name,                         int extension, pcsl_string * res_path) {    pcsl_string temp = PCSL_STRING_NULL;    MIDP_ERROR midpErr;    pcsl_string_status pcslErr;    *res_path = PCSL_STRING_NULL; /* null in case of any error */    if (pcsl_string_is_null(name)) {        return MIDP_ERROR_ILLEGAL_ARGUMENT;    }    midpErr = buildSuiteFilename(filenameBase, name, extension == IDX_EXTENSION_INDEX                                          ? MIDP_RMS_IDX_EXT : MIDP_RMS_DB_EXT,                                          res_path);    if (midpErr != MIDP_ERROR_NONE) {        return midpErr;    }    if (pcsl_string_is_null(res_path)) {        /* Assume this is special case where the suite was not installed           and create a filename from the ID. */        pcslErr = pcsl_string_cat(storage_get_root(storageId),            filenameBase, &temp);        if (pcslErr != PCSL_STRING_OK || pcsl_string_is_null(&temp) ) {            return MIDP_ERROR_FOREIGN;        }        pcslErr = pcsl_string_cat(&temp, name, res_path);        pcsl_string_free(&temp);        if (PCSL_STRING_OK != pcslErr)        {            return MIDP_ERROR_FOREIGN;        }    }    return MIDP_ERROR_NONE;}/** * Looks to see if the storage file for record store * identified by <code>uidPath</code> exists * * @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 true if the file exists, false if it does not. */int rmsdb_record_store_exists(pcsl_string* filenameBase,                              const pcsl_string* name,                              int extension) {    pcsl_string filename;    int intStatus;    /*     * 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, extension, &filename)) {        return 0;    }    if (pcsl_string_is_null(&filename)) {        return 0;    }    intStatus = storage_file_exists(&filename);    pcsl_string_free(&filename);    return 0 != intStatus;}/** * Removes the storage file for record store <code>filename</code> * if it exists. * * @param ppszError pointer to a string that will hold an error message *        if there is a problem, or null if the function is *        successful (This function sets <tt>ppszError</tt>'s value.) * @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 1 if successful *         0 if an IOException occurred *        -1 if file is locked by another isolate *        -2 if out of memory error occurs * */intrmsdb_record_store_delete(char** ppszError,                          pcsl_string* filenameBase,                          const pcsl_string* name_str,                          int extension) {    pcsl_string filename_str;#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 in use by another isolate */            *ppszError = (char *)FILE_LOCK_ERROR;            return -1;        }    }#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 -2;    }    storage_delete_file(ppszError, &filename_str);    pcsl_string_free(&filename_str);    if (*ppszError != NULL) {        return 0;    }    return 1;}/** * Returns the number of record stores owned by the * MIDlet suite. * * @param root storage root a MIDlet suite * * @return number of record stores or OUT_OF_MEM_LEN */static intrmsdb_get_number_of_record_stores_int(const pcsl_string* root) {    pcsl_string filename;    int numberOfStores = 0;    void* handle = NULL;    int errc = 0; /* 0 for ok, -1 for error -- see pcsl docs */    handle = storage_open_file_iterator(root);    if (!handle) {        return OUT_OF_MEM_LEN;    }    for(;;) {        errc = storage_get_next_file_in_iterator(root, handle, &filename);        if ( 0 != errc ) {            break;        }        if (pcsl_string_ends_with(&filename, &DB_EXTENSION)) {            numberOfStores++;        }        pcsl_string_free(&filename);    }    storageCloseFileIterator(handle);    return numberOfStores;}/** * Returns the number of record stores owned by the * MIDlet suite. * * @param filenameBase filenameBase of the MIDlet suite that owns the record  * store * * @return number of record stores or OUT_OF_MEM_LEN */intrmsdb_get_number_of_record_stores(pcsl_string* filenameBase) {    int numberOfStores;    /*     * IMPL_NOTE: for security reasons the record store is always     * located in the internal storage.     */    if (filenameBase->data == NULL) {        return 0;    }    numberOfStores = rmsdb_get_number_of_record_stores_int(filenameBase);    return numberOfStores;}/** * 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 */intrmsdb_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;}/** * 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 */intrmsdb_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) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -