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

📄 cache.c

📁 彩信MMS的全部代码
💻 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 + -