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

📄 cache.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 3 页
字号:
 *   the request comes from the history.
 * "isWTA": if this is > 0, only content belonging to WTA is considered,
 *    otherwise only content NOT belonging to WTA is considered
 * "uiLastMod" points to a location where the last modified time
 * will be stored, in case the function returns 2, and similarly
 * "etag" points to a location where a BYTE-pointer to an entity tag
 * will be stored.
 *
 * Return values:
 *   0 => the URL is not in the cache, or has expired and cannot be
 *        revalidated.
 *   1 => the URL is in the cache and has not expired.
 *   2 => the URL is in the cache, has expired, but can be revalidated;
 *        in this case, the last modified time is returned in
 *        the 'uiLastMod' parameter and the entity tag in "etag".
 */
INT16
Cache_URLisPresent (void *pvUrl,  /* URL, as null-terminated byte string */
                    UINT8 iWmlBackNav, /* the request comes from the history */
                    UINT8 isWTA,       /* */
                    UINT32 *uiLastMod,      /* return last modified time */
                    BYTE   **etag           /* return entity tag */
                    )
{
  CacheRecord rec;
  UINT32      currentTime;
  UINT8       cacheMode;
  ListNode    *p;

  if (!theCache.isInitialized) {
    return 0;
  }
  if (uiLastMod != NULL)
    *uiLastMod = 0;

  if ((pvUrl == NULL) || (uiLastMod == NULL)) {
    return 0;
  }

  /* Search for the record with matching URL */
  p = Cache_Find ((BYTE*) pvUrl, &rec, (INT16)(isWTA ? 1 : 0));

  if (p == NULL) {
    /* URL is not in the cache */
    return 0;
  }

  cacheMode = (UINT8)(theCache.waeMainObj->iCacheMode);
  currentTime = CLNTa_currentTime( );

  if ((rec.expire > currentTime) || (rec.expire == 0)) {
    /* URL is in the cache and has not expired, or will never expire. */
    return 1;
  }
  else if ( iWmlBackNav && !(rec.flags & MUSTREVALIDATE) ){
	/* URL is in the cache and has expired, but the request comes 
	  from the history and the MustRevalidate flag is not set. */
    return 1;
  }
  else if ((rec.last_mod != 0) || (rec.etag_len > 0)) {
    /* URL is in the cache, has expired, but has a last modified date
       or an entity tag.
       In this case, we might get away by revalidating the page with
       the server. Exception: the cache mode says we don't have
       to check; in this case we treat it as if it had not expired. */
    if (!(rec.flags & MUSTREVALIDATE) &&
        ((cacheMode == CACHE_MODE_NEVER_CHECK) ||
         ((cacheMode == CACHE_MODE_FIRSTTIME_CHECK) &&
          (rec.flags & HASREAD)))) {
      return 1;
    }
    else {
      if (rec.etag_len > 0) {
        *etag = NEWARRAY (BYTE, rec.etag_len + 1);
        if (*etag == NULL) {
          return 0;
        }
#ifdef FILE_CACHE
        FILEa_read ('C', p->id, *etag,
                    sizeof (CacheRecord) + rec.url_len + rec.header_len +
                    rec.body_len, rec.etag_len);
#else
        Storage_Get (&(theCache.store), p->id,
                     sizeof (CacheRecord) + rec.url_len + rec.header_len +
                     rec.body_len, rec.etag_len, *etag);
#endif
        (*etag)[rec.etag_len] = '\0';
      }
      else {
        *etag = NULL;
      }
      *uiLastMod = rec.last_mod;
      return 2;
    }
  }

  else {
    /* URL is in cache, has expired, and cannot be revalidated: remove it. */
#ifdef FILE_CACHE
    theCache.size -= FILEa_getSize ('C', p->id);
    FILEa_delete ('C', p->id);
#else
    Storage_DeleteBlock (&(theCache.store), p->id);
#endif
    list_out (p);
    DEALLOC (&p);

    return 0;
  }
}


/*
 * Cache_Read
 *
 * Given a URL, read the corresponding Header and Body from the cache.
 * "pvUrl" is the URL, as a null-terminated byte string,
 * "pvHeader" points to a location where a pointer to the header
 * contents will be stored, and "liHeaderLen" points to a location
 * where the length of the header will be stored.
 * Similarly, "pvBody" points to a location where a pointer to the body
 * contents will be stored, and "liBodLen" points to a location
 * where the length of the body will be stored.
 *
 * Returns 1 if successful, otherwise 0.
 */
INT16
Cache_Read (void* pvUrl,
            void **pvHeader, UINT32 *liHeaderLen,
            void **pvBody, UINT32 *liBodLen
            )
{
  CacheRecord rec;
  ListNode    *p;

  if (!theCache.isInitialized) {
    return 0;
  }

  if ((pvUrl == NULL)
      || (pvHeader == NULL)
      || (liHeaderLen == NULL)
      || (pvBody == NULL)
      || (liBodLen == NULL))
    return 0;

  p = Cache_Find ((BYTE*) pvUrl, &rec, -1);
  if (p == NULL)
    return 0;

  if (!(rec.flags & HASREAD)) {
    rec.flags |= HASREAD;
#ifdef FILE_CACHE
    if (FILEa_write ('C', p->id, &rec, 0, sizeof (CacheRecord))
        != sizeof (CacheRecord)) {
#else
    if (!Storage_Put (&(theCache.store), p->id, 0,
                      sizeof (CacheRecord), &rec)) {
#endif
      return 0;
    }
  }

  *pvHeader = NULL;
  *liHeaderLen = 0;
  *pvBody = NULL;
  *liBodLen = 0;

  if (rec.header_len > 0) {
    if ((*pvHeader = NEWARRAY (BYTE, rec.header_len)) == NULL) {
      return 0;
    }
#ifdef FILE_CACHE
    if (FILEa_read ('C', p->id, *pvHeader,
                    sizeof (CacheRecord) + rec.url_len,
                    rec.header_len) != rec.header_len) {
#else
    if (!Storage_Get (&(theCache.store), p->id,
                      sizeof (CacheRecord) + rec.url_len,
                      rec.header_len, *pvHeader)) {
#endif
      return 0;
    }
  }

  if (rec.body_len > 0) {
    if ((*pvBody = NEWARRAY (BYTE, rec.body_len)) == NULL) {
      DEALLOC (pvHeader);
      return 0;
    }
#ifdef FILE_CACHE
    if (FILEa_read ('C', p->id, *pvBody,
                    sizeof (CacheRecord) + rec.url_len + rec.header_len,
                    rec.body_len) != (INT32)rec.body_len) {
#else
    if (!Storage_Get (&(theCache.store), p->id,
                      sizeof (CacheRecord) + rec.url_len + rec.header_len,
                      rec.body_len, *pvBody)) {
#endif
      DEALLOC (pvHeader);
      DEALLOC (pvBody);
      return 0;
    }
  }

  *liHeaderLen = rec.header_len;
  *liBodLen = rec.body_len;

  return 1;
}


/*
 * Cache_GetParameters
 *
 * Compute Expire and LastModified from a Header.
 */
void
Cache_GetParameters (BYTE* pbHeader, UINT32 uiHeadLen,
                     UINT32 *uiExp,
                     UINT32 *uiLastMod,
                     UINT8  *uiMustRevalidate,
                     UINT32 *uiDate,
                     BYTE   **pbEtag)
{
  pHEADERDEF      pHeaderList = NULL;
  pHEADERELEMENT  pHeaderElement = NULL;
  UINT32          uiAge = 0;
  UINT32          uiExpire = 0;
  UINT32          uiNow = 0;
  unsigned char   ucCacheControl = 0;
  UINT32          uiDeltaSec = 0;
  BOOL            bError = FALSE;
  UINT8           uiEncVer = 0;

  *uiDate = 0;
  *uiExp = 0;
  *pbEtag = NULL;
  if (pbHeader == NULL)
    return;

  pHeaderList = WSP_PreParseHeaders (pbHeader, uiHeadLen, &bError);
  if (bError || (pHeaderList == NULL))
    return;

  if (pHeaderList->pHeadList == NULL) {
    DeleteHEADERDEF (pHeaderList);
    return;
  }

  /* Cache-Control Header */
  pHeaderElement = WSP_GetHeaderWK (1, Field_Cache_Control,
                                    pHeaderList->pHeadList);
  if( pHeaderElement == NULL ){
    pHeaderElement = WSP_GetHeaderWK ( 1, Field_Cache_Control_1_3, 
                                      pHeaderList->pHeadList );
	uiEncVer++;
    if( pHeaderElement == NULL ){
      pHeaderElement = WSP_GetHeaderWK ( 1, Field_Cache_Control_1_4,
                                        pHeaderList->pHeadList );
	  uiEncVer++;
	}
  }
  do {
    if (pHeaderElement == NULL)
      break;
    ucCacheControl = WSP_GetCacheControlByte (pHeaderElement,
                                              &uiDeltaSec, &bError);
    /* Must-Revalidate, Proxy-Revalidate */
    if ((ucCacheControl == 137 || ucCacheControl == 138) && !bError ) {
      *uiMustRevalidate = 1;
    }		/* Max-Age */
    else if ((ucCacheControl == 130) && !bError) {
      uiNow = CLNTa_currentTime ();
      *uiExp = uiNow + uiDeltaSec;
    }
    /* Second CacheDirective */
    if (pHeaderElement->pNext == NULL)
      break;
	if( uiEncVer == 0 )
      pHeaderElement = WSP_GetHeaderWK (1, Field_Cache_Control,
                                        pHeaderElement->pNext);
    else if( uiEncVer == 1 )
      pHeaderElement = WSP_GetHeaderWK (1, Field_Cache_Control_1_3, 
                                        pHeaderElement->pNext);
    else if( uiEncVer == 2 )
        pHeaderElement = WSP_GetHeaderWK (1, Field_Cache_Control_1_4,
                                          pHeaderElement->pNext);
    if (pHeaderElement == NULL)
      break;
    ucCacheControl = WSP_GetCacheControlByte (pHeaderElement,
                                              &uiDeltaSec, &bError);
    /* Must-Revalidate, Proxy-Revalidate */
    if (((ucCacheControl == 137) || (ucCacheControl == 138)) && !bError) {
      *uiMustRevalidate = 1;
    }	/* Max-Age */
    else if ((ucCacheControl == 130) && !bError) {
      uiNow = CLNTa_currentTime ();
      *uiExp = uiNow + uiDeltaSec;
    }
  } while (0);


  bError = FALSE;
  /* Date Header */
  pHeaderElement = WSP_GetHeaderWK (1, Field_Date,
                                    pHeaderList->pHeadList);
  if (pHeaderElement != NULL)
    *uiDate = WSP_GetDate (pHeaderElement, &bError);

  if ((*uiExp == 0) && (*uiDate > 0)) {
    bError = FALSE;
    /* Expire Header */
    pHeaderElement = WSP_GetHeaderWK (1, Field_Expires,
                                      pHeaderList->pHeadList);
    if (pHeaderElement != NULL) {
      uiExpire = WSP_GetExpires (pHeaderElement, &bError);
      if ((uiExpire == 0) || bError)
        *uiExp = 1;
      else if (uiExpire > 0) {
        /* Age Header */
        pHeaderElement = WSP_GetHeaderWK (1, Field_Age,
                                          pHeaderList->pHeadList);
        if (pHeaderElement != NULL) {
          uiAge = WSP_GetAge (pHeaderElement, &bError);
        }
        uiNow = CLNTa_currentTime ();
        if (uiExpire > (*uiDate + uiAge))
          *uiExp = uiNow + (uiExpire - (*uiDate + uiAge));
        else
          *uiExp = uiNow;
      }
    }
  }

  bError = FALSE;
  /* Last-Modified Header */
  pHeaderElement = WSP_GetHeaderWK (1, Field_Last_Modified,
                                    pHeaderList->pHeadList);
  if (pHeaderElement != NULL) {
    *uiLastMod = WSP_GetLastModified (pHeaderElement, &bError);
  }

  bError = FALSE;
  /* E-Tag Header */
  pHeaderElement = WSP_GetHeaderWK (1, Field_Etag,
                                    pHeaderList->pHeadList);
  if (pHeaderElement != NULL) {
    BYTE   *tmp = WSP_GetEtag (pHeaderElement);
    UINT16 etag_len = B_STRINGLENGTH (tmp);

    *pbEtag = NEWARRAY (BYTE, etag_len + 1);
    if (*pbEtag != NULL) {
      B_COPYSTRING (*pbEtag, tmp);
    }        
  }

  DeleteHEADERDEF (pHeaderList);
}


/*
 * Cache_Write
 *
 * Write a URL, Header and Body to the cache.
 * "pvUrl" is the URL, as a null-terminated byte string,
 * "isWTA", if > 0, this content is flagged as belonging to WTA
 * "pvHeader" points to the header content and "iHeaderLen" is the length
 * of the header. Similarly, "pvBody" points to the body content and
 * "iBodLen" is the length of the body.
 *
 * Returns 1 if successful, otherwise 0.
 */
INT16
Cache_Write (void *pvUrl,
             UINT8 isWTA,
             void *pvHeader, UINT32 iHeaderLen,
             void *pvBody, UINT32 iBodLen
             )
{
  CacheRecord rec;
  UINT32      pos, tot_len, newid;
  UINT16      etag_len = 0, url_len = 0;
  UINT32      currentTime, expire = 0, lastModified = 0, date = 0;
  UINT8       mustRevalidate = 0;
  BYTE*       etag = NULL;
  ListNode    *p;

  if (!theCache.isInitialized) {
    return 0;
  }
  if ((pvUrl == NULL)
      || (pvHeader == NULL)
      || (iHeaderLen == 0)
      || (pvBody == NULL)
      || (iBodLen == 0)) {
    return 0;
  }

  Cache_GetParameters ((BYTE*) pvHeader, iHeaderLen, &expire, &lastModified,
                       &mustRevalidate, &date, &etag );

  if (expire == 0 && mustRevalidate == 0) {
    if (theCache.waeMainObj != NULL) {
      currentTime = CLNTa_currentTime ();
      expire = currentTime + theCache.waeMainObj->iDefaultExpireTime;
    }

⌨️ 快捷键说明

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