suitestore_icon_cache.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 606 行 · 第 1/2 页

C
606
字号
/* * * * Copyright  1990-2008 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. *//** * @file * * @ingroup AMS * * This is reference implementation of the Suite Storage Listeners API. * It allows to register/unregister callbacks that will be notified * when the certain operation on a midlet suite is performed. */#include <string.h>#include <pcsl_memory.h>#include <midpInit.h>#include <suitestore_intern.h>#include <suitestore_icon_cache.h>/** * Maximal number of free entries allowed in the file containing the cache until * it is compacted (i.e. rewritten without free entries). */#define MAX_FREE_ENTRIES 10/** * A number of additional free entries that will be allocated in * g_pIconCache array to avoid memory reallocations when a new * icon is added into the cache. */#define RESERVED_CACHE_ENTRIES_NUM 10/** * An array of IconCache structures representing * the icon cache in the memory. */static IconCache* g_pIconCache = NULL;/** A flag indicating if the icon cache is loaded from file into memory. */static int g_iconsLoaded = 0;/** Number of currently occupied entries in the g_pIconCache array. */static int g_numberOfIcons = 0;/** Number of entries currently allocated in the g_pIconCache array. */static int g_numberOfEntries = 0;#define ADJUST_POS_IN_BUF(pos, bufferLen, n) \    pos += n; \    bufferLen -= n;/** * Search for a structure containing the cached suite's icon(s) * by the suite's ID. * * @param suiteId unique ID of the midlet suite * * @return pointer to the IconCache structure containing * the cached suite's icon(s) or NULL if the it was not found */static IconCache*get_icon_cache_for_suite(SuiteIdType suiteId) {    IconCache* pData;    int i;    if (!g_iconsLoaded) {        MIDPError status = midp_load_suites_icons();        if (status != ALL_OK) {            return NULL;        }    }    pData = g_pIconCache;    /* search the given suite Id in the array of cache entries */    for (i = 0; i < g_numberOfIcons; i++) {        if (g_pIconCache[i].suiteId == suiteId) {            return &g_pIconCache[i];        }    }    return NULL;}/** * Initializes the icons cache. * * @return status code: ALL_OK if no errors, *         OUT_OF_MEMORY if malloc failed *         IO_ERROR if an IO_ERROR */MIDPError midp_load_suites_icons() {    int i;    long bufferLen, pos, alignedOffset;    char* buffer = NULL;    char* pszError = NULL;    unsigned char* pIconBytes;    pcsl_string_status rc;    pcsl_string iconsCacheFile;    IconCache *pIconsData, *pData;    IconCacheHeader* pCacheFileHeader;    IconCacheEntry* pNextCacheEntry;    int numOfIcons = 0, numOfEntries = 0;    MIDPError status;    if (g_iconsLoaded) {        return ALL_OK;    }    if (midpInit(LIST_LEVEL) != 0) {        return OUT_OF_MEMORY;    }    /* get a full path to the _suites.dat */    rc = pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID),                         &ICON_CACHE_FILENAME, &iconsCacheFile);    if (rc != PCSL_STRING_OK) {        return OUT_OF_MEMORY;    }    /* read the file */    status = read_file(&pszError, &iconsCacheFile, &buffer, &bufferLen);    pcsl_string_free(&iconsCacheFile);    storageFreeError(pszError);    if (status == NOT_FOUND || (status == ALL_OK && bufferLen == 0)) {        /* _icons.dat is absent or empty, it's a normal situation */        g_pIconCache  = NULL;        g_iconsLoaded = 1;        return ALL_OK;    }    if (status == ALL_OK && bufferLen < (long)(sizeof(unsigned long)<<1)) {        status = IO_ERROR; /* _icons.dat is corrupted */    }    if (status != ALL_OK) {        pcsl_mem_free(buffer);        return status;    }    /* parse its contents */    pos = 0;    /* checking the file header */    pCacheFileHeader = (IconCacheHeader*)buffer;    if (pCacheFileHeader->magic   != ICON_CACHE_MAGIC ||        pCacheFileHeader->version != ICON_CACHE_VERSION ||        pCacheFileHeader->numberOfFreeEntries >            pCacheFileHeader->numberOfEntries) {        pcsl_mem_free(buffer);        return IO_ERROR;    }    numOfIcons   = pCacheFileHeader->numberOfEntries -                       pCacheFileHeader->numberOfFreeEntries;    numOfEntries = numOfIcons + RESERVED_CACHE_ENTRIES_NUM;    ADJUST_POS_IN_BUF(pos, bufferLen, sizeof(IconCacheHeader));    pIconsData = (IconCache*) pcsl_mem_malloc(sizeof(IconCache) * numOfEntries);    if (pIconsData == NULL) {        pcsl_mem_free(buffer);        return OUT_OF_MEMORY;    }    /* iterating through the cache entries */    for (i = 0; i < pCacheFileHeader->numberOfEntries; i++) {        if ((long)sizeof(IconCacheEntry) > bufferLen) {            status = IO_ERROR;            break;        }        pNextCacheEntry = (IconCacheEntry*)&buffer[pos];        if (pNextCacheEntry->isFree) {            alignedOffset = sizeof(IconCacheEntry) +                pNextCacheEntry->nameLength + pNextCacheEntry->imageDataLength;            alignedOffset = SUITESTORE_ALIGN_4(alignedOffset);            ADJUST_POS_IN_BUF(pos, bufferLen, alignedOffset);            continue;        }        pData = &pIconsData[i];        pData->suiteId = pNextCacheEntry->suiteId;        pData->numberOfCachedImages = 1;        pData->pInfo[0].isFree = 0;        pData->pInfo[0].entryOffsetInFile = pos;        pData->pInfo[0].pImageData = (unsigned char*)pcsl_mem_malloc(            pNextCacheEntry->imageDataLength);        if (pData->pInfo[0].pImageData == NULL) {            status = OUT_OF_MEMORY;            break;        }        pIconBytes = (unsigned char*)pNextCacheEntry + sizeof(IconCacheEntry) +            pNextCacheEntry->nameLength;        if (sizeof(IconCacheEntry) + pNextCacheEntry->nameLength +                pNextCacheEntry->imageDataLength > (unsigned long)bufferLen) {            status = IO_ERROR;            break;        }        pData->pInfo[0].imageDataLength = pNextCacheEntry->imageDataLength;        memcpy(pData->pInfo[0].pImageData, pIconBytes,               pNextCacheEntry->imageDataLength);        rc = pcsl_string_convert_from_utf16(            (jchar*)((char*)pNextCacheEntry + sizeof(IconCacheEntry)),            pNextCacheEntry->nameLength >> 1,            &pData->pInfo[0].imageName);        if (rc != PCSL_STRING_OK) {            status = OUT_OF_MEMORY;            break;        }        alignedOffset = sizeof(IconCacheEntry) +            pNextCacheEntry->nameLength + pNextCacheEntry->imageDataLength;        alignedOffset = SUITESTORE_ALIGN_4(alignedOffset);        ADJUST_POS_IN_BUF(pos, bufferLen, alignedOffset);    } /* end for (numOfEntries) */    if (status == ALL_OK) {        g_numberOfIcons = numOfIcons;        g_numberOfEntries = numOfEntries;        g_pIconCache    = pIconsData;        g_iconsLoaded   = 1;        if (pCacheFileHeader->numberOfFreeEntries > MAX_FREE_ENTRIES) {            (void)midp_compact_icons();        }    } else {        /* IMPL_NOTE: free the memory allocated for the image itself */        pcsl_mem_free(pIconsData);    }    pcsl_mem_free(buffer);    return status;}/** * Writes the cache contents into the icon cache file. * * @param pIconCache currently unused; may be useful to optimize *                   the writing of the file * * @return status code: ALL_OK if no errors, *         OUT_OF_MEMORY if malloc failed *         IO_ERROR if an IO_ERROR */static MIDPError store_suites_icons(const IconCache* pIconCache) {    MIDPError status = ALL_OK;    int i;    long bufferLen, pos, alignedOffset;    char* buffer = NULL;    char *pszError = NULL;    pcsl_string_status rc;    pcsl_string iconsCacheFile;    IconCache *pData;    IconCacheHeader* pCacheFileHeader;    IconCacheEntry* pNextCacheEntry;    if (pIconCache == NULL) {        return BAD_PARAMS;    }    /* IMPL_NOTE: currently the whole file is rewritten */    /* get a full path to the _icons.dat */    rc = pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID),                         &ICON_CACHE_FILENAME, &iconsCacheFile);    if (rc != PCSL_STRING_OK) {        return OUT_OF_MEMORY;    }    if (!g_numberOfIcons) {        /* there are no icons to cache, truncate the file */        status = write_file(&pszError, &iconsCacheFile, buffer, 0);

⌨️ 快捷键说明

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