midp_file_cache.c

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

C
530
字号
}int midp_file_cache_open(char** ppszError, StorageIdType storageId,                         const pcsl_string* filename, int ioMode) {    int h;    *ppszError = NULL;    h = storage_open(ppszError, filename, ioMode);    if (*ppszError == NULL) { /* Open successfully */        if (mFileCache == NULL) {            initFileCacheLimit();            mFileCache = (MidpFileCache *)midpMalloc(sizeof(MidpFileCache));            mFileCache->handle = h;            mFileCache->size = 0;            mFileCache->storageId = storageId;            mFileCache->cachedPosition = 0;            mFileCache->cachedAvailableSpace = UNINITIALIZED_CACHED_VALUE;            mFileCache->cachedFileSize = storageSizeOf(ppszError, h);            mFileCache->blocks = NULL;        } else {            /* More than one file is open. Available space can no longer been             * cached. Stop caching completely. */            midp_file_cache_finalize(ppszError, KNI_TRUE);        }    }    return h;}void midp_file_cache_close(char** ppszError, int handle) {    char *pszErrorTmp = NULL;    *ppszError = NULL;    if (mFileCache != NULL && mFileCache->handle == handle) {        midp_file_cache_finalize(ppszError, KNI_FALSE);        pszErrorTmp = *ppszError;    }    storageClose(ppszError, handle);    if (*ppszError == NULL) {        *ppszError = pszErrorTmp;    } else {        storageFreeError(pszErrorTmp);    }}void midp_file_cache_seek(char** ppszError, int handle, long position) {    *ppszError = NULL;    if (position >= 0 && mFileCache != NULL && mFileCache->handle == handle) {        mFileCache->cachedPosition = position;    } else {        storagePosition(ppszError, handle, position);    }}void midp_file_cache_write(char** ppszError, int handle,                           char* buffer, long length) {    MidpFileCacheBlock *p, *b;    *ppszError = NULL;    if (length <= 0) {        return;    }    if (mFileCache == NULL || mFileCache->handle != handle) {        storageWrite(ppszError, handle, buffer, length);        return;    }    /* Try to cache it */    p = NULL; /* the block previous to b */    b = mFileCache->blocks;    while (b != NULL) {        if (is_overlap(b->position, b->length,                       mFileCache->cachedPosition, length)) {            /* Handle simple overriding case */            if (is_include(b->position, b->length,                           mFileCache->cachedPosition, length)) {                memcpy(DATA(b) + mFileCache->cachedPosition - b->position,                        buffer, length);                updateCachedSizes(length);                return;            } else {                /* Flush everything out */                midp_file_cache_flush(ppszError, handle);                /* Reset previous block pointer after flush */                p = NULL;                /* Try to cache this write below */                break;            }        } else if (mFileCache->cachedPosition+length <= b->position) {            /* No match. Try to cache this write below */            break;        } else {            /* Continue to scan the next block */            p = b;            b = b->next; /* that is, p->next == b */        }    } /* end of while (b) */    /* the current value of b will not be used below */    /* This is a new write block that has not been cached */    /* Never try to cache large write that is bigger than cache limit */    if (sizeof(MidpFileCacheBlock)+length > fileCacheLimit) {        uncachedWrite(ppszError, handle, buffer, length);        return;    }    /* If cache is full, flush it before caching new write */    if (mFileCache->size+sizeof(MidpFileCacheBlock)+length > fileCacheLimit) {        midp_file_cache_flush(ppszError, handle);        /* Reset previous block pointer after flush */        p = NULL;    }    /* Cache is not full, check if memory is full */    b = (MidpFileCacheBlock *)midpMalloc(sizeof(MidpFileCacheBlock)+length);    if (b == NULL) {        /* Out of memory. Write directly to storage */        uncachedWrite(ppszError, handle, buffer, length);        return;    }    /* Insert a new cache block (b) between p and p->next */    b->position = mFileCache->cachedPosition;    b->length = length;    memcpy(DATA(b), buffer, length);    if (p == NULL) {        /* inserting in the beginning of the list */        b->next = mFileCache->blocks;        mFileCache->blocks = b;    } else {        /* inserting after p, in the middle of the list */        b->next = p->next;        p->next = b;    }    mFileCache->size += sizeof(MidpFileCacheBlock)+length;    updateCachedSizes(length);}long midp_file_cache_read(char** ppszError, int handle,                          char* buffer, long length) {    MidpFileCacheBlock *b;    long l;    *ppszError = NULL;    if (length <= 0) {        return 0;    }    if (mFileCache == NULL || mFileCache->handle != handle) {        return storageRead(ppszError, handle, buffer, length);    }    /* See if it is in the cache */    b = mFileCache->blocks;    while (b != NULL) {        if (is_overlap(b->position, b->length,                        mFileCache->cachedPosition, length)) {            /* Handle simple inclusive case */            if (is_include(b->position, b->length,                           mFileCache->cachedPosition, length)) {                /* Read from cache */                memcpy(buffer,                        DATA(b) + mFileCache->cachedPosition - b->position,                        length);                mFileCache->cachedPosition += length;                return length;            } else {                /* Flush everything out */                midp_file_cache_flush(ppszError, handle);                /* Read from file below */                break;            }        } else if (mFileCache->cachedPosition+length <= b->position) {            /* No match. Read from file below */            break;        } else {            /* Continue to scan the next block */            b = b->next;        }    } /* end of while (b) */    /* Read from file */    storagePosition(ppszError, handle, mFileCache->cachedPosition);    if (*ppszError == NULL) {        l = storageRead(ppszError, handle, buffer, length);        if (*ppszError == NULL) {            mFileCache->cachedPosition += length;        }    } else {        l = 0;    }    return l;}jlong midp_file_cache_available_space(char** ppszError, int handle,                                      StorageIdType storageId) {    /* Storage may have more then 2Gb space available so use 64-bit type */    jlong availSpace;    *ppszError = NULL;    if (mFileCache == NULL) {        availSpace = storage_get_free_space(storageId);    } else {        if (mFileCache->handle != handle) {            /* Flush current cache to storage before query for new space */            midp_file_cache_flush(ppszError, mFileCache->handle);            mFileCache->storageId = storageId;            mFileCache->cachedAvailableSpace = UNINITIALIZED_CACHED_VALUE;        }        if (mFileCache->cachedAvailableSpace == UNINITIALIZED_CACHED_VALUE) {            midp_init_cached_free_space();        }        availSpace = mFileCache->cachedAvailableSpace;    }    return availSpace;}long midp_file_cache_sizeof(char** ppszError, int handle) {    *ppszError = NULL;    if (mFileCache == NULL || mFileCache->handle != handle) {        return storageSizeOf(ppszError, handle);    } else {        return mFileCache->cachedFileSize;    }}void midp_file_cache_truncate(char** ppszError, int handle, long size) {    *ppszError = NULL;    midp_file_cache_flush(ppszError, handle);    CHECK_ERROR(*ppszError);    storageTruncate(ppszError, handle, size);    if (*ppszError == NULL && mFileCache != NULL) {        if (mFileCache->handle != handle) {            mFileCache->cachedAvailableSpace = UNINITIALIZED_CACHED_VALUE;        } else {            if (mFileCache->cachedAvailableSpace !=                    UNINITIALIZED_CACHED_VALUE) {                mFileCache->cachedAvailableSpace +=                    mFileCache->cachedFileSize - size;                mFileCache->cachedFileSize = size;            }        }    }}

⌨️ 快捷键说明

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