📄 cache.c
字号:
/*
* Copyright (C) Obigo AB, 2002-2005.
* All rights reserved.
*
* This software is covered by the license agreement between
* the end user and Obigo AB, and may be
* used and copied only in accordance with the terms of the
* said agreement.
*
* Obigo AB assumes no responsibility or
* liability for any errors or inaccuracies in this software,
* or any consequential, incidental or indirect damage arising
* out of the use of the software.
*
*/
#include "cansilib.h"
#include "cmnconf.h"
#include "aapifile.h"
#include "aapicmn.h"
#include "cutils.h"
#include "gmem.h"
#include "fldrmgr.h"
#include "cache.h"
typedef struct
{
CmnClientId client;
char category;
UINT32 fileId;
unsigned char *buf;
CMN_BOOL isDirty;
UINT32 size;
UINT32 fill;
UINT32 startPos;
} CmnCache;
static FmResult cacheFileFlush(CmnCache *cache);
FmResult cacheFileClose(void *p)
{
CmnCache *cache = (CmnCache *)p;
FmResult fmResult = FM_RESULT_OK;
if (cache != NULL)
{
if (cache->isDirty)
{
fmResult = cacheFileFlush(cache);
}
FILEa_close( cache->category, cache->fileId);
G_FREE( cache->client, cache->buf);
G_FREE( cache->client, cache);
}
return fmResult;
}
static FmResult cacheFileFlush(CmnCache *cache)
{
INT32 written;
FmResult fmResult = FM_RESULT_OK;
if (cache != NULL && cache->fill > 0)
{
written = FILEa_write( cache->category, cache->fileId, cache->buf,
(INT32)cache->startPos, (INT32)cache->fill);
if (written < 0 || (UINT32)written < cache->fill)
{
fmResult = FM_RESULT_DISK_FULL;
}
cache->startPos += cache->fill;
cache->fill = 0;
}
return fmResult;
}
FmResult cacheFileOpen( void **p, CmnClientId client, UINT32 cacheSize,
char category, UINT32 *fileId)
{
CmnCache **cache = (CmnCache **)p;
if (*fileId == 0 || FILEa_open( category, *fileId, FM_READ_WRITE) != 0)
{
if (FILEa_create( category, NULL, fileId) != 0)
{
CMN_LOG_I(("%s(%d): FILEa_create returned error\n",
__FILE__, __LINE__));
*cache = NULL;
return FM_RESULT_DISK_FULL;
}
}
*cache = G_CALLOC( client, sizeof(CmnCache));
(*cache)->client = client;
(*cache)->category = category;
(*cache)->fileId = *fileId;
(*cache)->buf = G_CALLOC( client, cacheSize);
(*cache)->isDirty = FALSE;
(*cache)->size = cacheSize;
(*cache)->startPos = 0;
(*cache)->fill = 0;
return FM_RESULT_OK;
}
FmResult cacheFileRead( void *p, void *data, UINT32 size, UINT32 pos,
UINT32 *bytesRead)
{
CmnCache *cache = (CmnCache *)p;
FmResult fmResult = FM_RESULT_OK;
INT32 returnSize = 0;
UINT32 readSize = 0;
UINT32 readPos = 0;
void *readDest = NULL;
CMN_BOOL shouldBypassCache = FALSE;
if (cache == NULL)
{
CMN_LOG_I(("%s(%d): no data\n", __FILE__, __LINE__));
return FM_RESULT_ERROR;
}
*bytesRead = 0;
if (pos >= cache->startPos &&
pos + size <= cache->startPos + cache->fill)
{
}
else if (size >= cache->size)
{
readSize = size;
readDest = data;
readPos = pos;
shouldBypassCache = TRUE;
}
else if (pos < cache->startPos ||
pos + size >= cache->startPos + cache->fill)
{
readSize = cache->size;
readDest = cache->buf;
readPos = pos;
}
else
{
*bytesRead = pos - cache->startPos + cache->size - cache->fill;
memcpy( data, &cache->buf[pos - cache->startPos], *bytesRead);
size -= *bytesRead;
data = (char *)data + *bytesRead;
readSize = cache->size;
readDest = cache->buf;
readPos = pos + *bytesRead;
}
if (readSize > 0)
{
returnSize = FILEa_read( cache->category, cache->fileId, readDest,
(INT32)readPos, (INT32)readSize);
if (returnSize < 0)
{
CMN_LOG_I(("%s(%d): FILEa_read(%c,%lu,ptr,%lu,%lu) returned %d\n",
__FILE__, __LINE__, cache->category, cache->fileId,
readPos, readSize, returnSize));
fmResult = FM_RESULT_FILE_ERROR;
}
else if (shouldBypassCache)
{
*bytesRead = (UINT32)returnSize;
}
else if (returnSize < (INT32)size)
{
size = (UINT32)returnSize;
}
cache->fill = size;
}
if (fmResult == FM_RESULT_OK &&
pos + size <= cache->startPos + cache->fill &&
shouldBypassCache == FALSE)
{
memcpy( data, &cache->buf[ cache->startPos - pos ], size);
*bytesRead += size;
}
return fmResult;
}
FmResult cacheFileWrite( void *p, void *data, UINT32 size, UINT32 pos)
{
CmnCache *cache = (CmnCache *)p;
FmResult fmResult = FM_RESULT_OK;
INT32 fileSize;
INT32 written;
if (cache == NULL)
{
CMN_LOG_I(("%s(%d): no data\n", __FILE__, __LINE__));
return FM_RESULT_ERROR;
}
cache->isDirty = TRUE;
if (pos == FM_APPEND)
{
fileSize = FILEa_getSize( cache->category, cache->fileId);
if (fileSize < 0)
{
CMN_LOG_I(("%s(%d): FILEa_getSize returned %d\n",
__FILE__, __LINE__, fileSize));
return FM_RESULT_FILE_ERROR;
}
else
{
pos = CMN_MAX( (UINT32)fileSize, cache->startPos + cache->fill);
}
}
if (pos < cache->startPos ||
pos + size > cache->startPos + cache->size)
{
if (cache->fill > 0)
{
written = FILEa_write( cache->category, cache->fileId, cache->buf,
(INT32)cache->startPos, (INT32)cache->fill);
if (written < 0 || (UINT32)written < cache->fill)
{
fmResult = FM_RESULT_DISK_FULL;
}
}
cache->startPos = pos;
cache->fill = 0;
}
if (size > cache->size)
{
written = FILEa_write( cache->category, cache->fileId, data,
(INT32)pos, (INT32)size);
if (written < 0 || (UINT32)written < size)
{
fmResult = FM_RESULT_DISK_FULL;
}
}
else
{
memcpy( &cache->buf[pos - cache->startPos], data, size);
if (pos + size >= cache->startPos + cache->fill)
{
cache->fill = pos + size;
}
}
return fmResult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -