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

📄 cache.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
📖 第 1 页 / 共 3 页
字号:
         a_Nav_push(bw, NewUrl);         a_Url_free(NewUrl);      } else {         /* Sub entity redirection (most probably an image) */         if ( !entry->ValidSize ) {            DEBUG_MSG(3,">>>Image redirection without entity-content<<<\n");         } else {            DEBUG_MSG(3, ">>>Image redirection with entity-content<<<\n");         }      }   }   return 0;}/* * Do nothing, but let the cache fill the entry. * (Currently used to ignore image redirects  --Jcid) */void a_Cache_null_client(int Op, CacheClient_t *Client){ return;}/* * Update cache clients for a single cache-entry * Tasks: *   - Set the client function (if not already set) *   - Look if new data is available and pass it to client functions *   - Remove clients when done *   - Call redirect handler * * todo: Implement CA_Abort Op in client callback */static void Cache_process_queue(CacheData_t *entry){   gint i, st;   CacheClient_t *Client;   DilloWeb *ClientWeb;   BrowserWindow *Client_bw = NULL;   static gboolean Busy = FALSE;   gboolean AbortEntry = FALSE;   if ( Busy )      DEBUG_MSG(5, "FATAL!:*** >>>> Cache_process_queue Caught busy!!!\n");   Busy = TRUE;   if ( !(entry->Flags & CA_GotHeader) ) {      Busy = FALSE;      return;   }   for ( i = 0; (Client = g_slist_nth_data(ClientQueue, i)); ++i ) {      if ( Client->Url == entry->Url ) {         ClientWeb = Client->Web;    /* It was a (void*) */         Client_bw = ClientWeb->bw;  /* 'bw' in a local var */         if (ClientWeb->flags & WEB_RootUrl) {            if (!(entry->Flags & CA_MsgErased)) {               /* clear the "expecting for reply..." message */               a_Interface_msg(Client_bw, "");               entry->Flags |= CA_MsgErased;            }            if (entry->Flags & CA_Redirect)               Client->Callback = a_Cache_null_client;         } else {            /* For non root URLs, ignore redirections and 404 answers */            if (entry->Flags & CA_Redirect || entry->Flags & CA_NotFound)               Client->Callback = a_Cache_null_client;         }         /* Set the client function */         if (!Client->Callback) {            st = a_Web_dispatch_by_type(entry->Type, ClientWeb,                                        &Client->Callback, &Client->CbData);            if (st == -1) {               /* MIME type is not viewable */               Client->Callback = a_Cache_null_client;               Client->CbData = NULL;               if (ClientWeb->flags & WEB_RootUrl) {                  /* Unhandled MIME type, prepare a download offer... */                  AbortEntry = TRUE;                  a_Interface_remove_client(Client_bw, Client->Key);                  Cache_client_dequeue(Client, NULLKey);                  --i; /* Keep the index value in the next iteration */                  continue;               }            }         }         /* Send data to our client */         if ( (Client->BufSize = entry->ValidSize) > 0) {            Client->Buf = (guchar *)entry->Data;            (Client->Callback)(CA_Send, Client);         }         /* Remove client when done */         if ( (entry->Flags & CA_GotData) ) {            /* Copy flags to a local var */            gint flags = ClientWeb->flags;            /* We finished sending data, let the client know */            if (!Client->Callback)               DEBUG_MSG(3, "Client Callback is NULL");            else               (Client->Callback)(CA_Close, Client);            Cache_client_dequeue(Client, NULLKey);            --i; /* Keep the index value in the next iteration */            if ( entry->Flags & CA_Redirect )               Cache_redirect(entry, flags, Client_bw);         }      }   } /* for */   if (AbortEntry) {      /* Abort the entry, remove it from cache, and offer download.       * (the dialog is made before 'entry' is freed) */      a_Interface_offer_link_download(Client_bw, entry->Url);      Cache_entry_remove(entry, NULL);   }   Busy = FALSE;   DEBUG_MSG(1, "QueueSize ====> %d\n", g_slist_length(ClientQueue));}/* * Callback function for Cache_delayed_process_queue. */static gint Cache_delayed_process_queue_callback(gpointer data){   gpointer entry;   while ((entry = g_slist_nth_data(DelayedQueue, 0))) {      Cache_process_queue( (CacheData_t *)entry );      /* note that if Cache_process_queue removes the entry,       * the following g_slist_remove has no effect. */      DelayedQueue = g_slist_remove(DelayedQueue, entry);   }   DelayedQueueIdleId = 0;   return FALSE;}/* * Set a call to Cache_process_queue from the gtk_main cycle. */static void Cache_delayed_process_queue(CacheData_t *entry){   /* there's no need to repeat entries in the queue */   if (!g_slist_find(DelayedQueue, entry))      DelayedQueue = g_slist_prepend(DelayedQueue, entry);   if (DelayedQueueIdleId == 0)      DelayedQueueIdleId =         gtk_idle_add((GtkFunction)Cache_delayed_process_queue_callback, NULL);}/* * Remove a cache client * todo: beware of downloads */static void Cache_remove_client_raw(CacheClient_t *Client, gint Key){   Cache_client_dequeue(Client, Key);}/* * Remove every Interface-client of a single Url. * todo: beware of downloads * (this is transitory code) */static void Cache_remove_interface_clients(const DilloUrl *Url){   gint i;   DilloWeb *Web;   CacheClient_t *Client;   for ( i = 0; (Client = g_slist_nth_data(ClientQueue, i)); ++i ) {      if ( Client->Url == Url ) {         Web = Client->Web;         a_Interface_remove_client(Web->bw, Client->Key);      }   }}/* * Remove a client from the client queue * todo: notify the dicache and upper layers */static void Cache_stop_client(gint Key, gint force){   CacheClient_t *Client;   CacheData_t *entry;   GSList *List;   DilloUrl *url;   if (!(List = g_slist_find_custom(ClientQueue, GINT_TO_POINTER(Key),                                    Cache_client_key_cmp))){      DEBUG_MSG(5, "WARNING: Cache_stop_client, inexistent client\n");      return;   }   Client = List->data;   url = (DilloUrl *)Client->Url;   Cache_remove_client_raw(Client, NULLKey);   if (force &&       !g_slist_find_custom(ClientQueue, url, Cache_client_url_cmp)) {      /* it was the last client of this entry */      if ((entry = Cache_entry_search(url))) {         if (entry->CCCQuery) {            a_Cache_ccc(OpAbort, 1, BCK, entry->CCCQuery, NULL, NULL);         } else if (entry->CCCAnswer) {            a_Cache_ccc(OpStop, 2, BCK, entry->CCCAnswer, NULL, Client);         }      }   }}/* * Remove a client from the client queue * (It may keep feeding the cache, but nothing else) */void a_Cache_stop_client(gint Key){   Cache_stop_client(Key, 0);}/* * CCC function for the CACHE module */void a_Cache_ccc(int Op, int Branch, int Dir, ChainLink *Info,                 void *Data1, void *Data2){   CacheData_t *entry;   a_Chain_debug_msg("a_Cache_ccc", Op, Branch, Dir);   if ( Branch == 1 ) {      if (Dir == BCK) {         /* Querying branch */         switch (Op) {         case OpStart:            /* Localkey = entry->Url */            Info->LocalKey = Data2;            break;         case OpStop:            break;         case OpAbort:            Cache_entry_remove_raw(NULL, Info->LocalKey);            a_Chain_bcb(OpAbort, Info, NULL, NULL);            g_free(Info);            break;         }      } else {  /* FWD */         switch (Op) {         case OpSend:            /* Start the answer-reading chain */            a_Cache_ccc(OpStart, 2, BCK, a_Chain_new(), Data1, Info->LocalKey);            break;         case OpEnd:            /* unlink HTTP_Info */            a_Chain_del_link(Info, BCK);            /* 'entry->CCCQuery' and 'Info' point to the same place! */            if ((entry = Cache_entry_search(Info->LocalKey)) != NULL)               entry->CCCQuery = NULL;            g_free(Info);            break;         case OpAbort:            /* Unlink HTTP_Info */            a_Chain_del_link(Info, BCK);            /* remove interface client-references of this entry */            Cache_remove_interface_clients(Info->LocalKey);            /* remove clients of this entry */            Cache_stop_clients(Info->LocalKey, 0);            /* remove the entry */            Cache_entry_remove_raw(NULL, Info->LocalKey);            g_free(Info);            break;         }      }   } else if (Branch == 2) {      if (Dir == FWD) {         /* Answering branch */         switch (Op) {         case OpStart:            /* Data2 = entry->Url */            Info->LocalKey = Data2;            if ((entry = Cache_entry_search(Info->LocalKey))) {               entry->CCCAnswer = Info;            } else {               /* The cache-entry was removed */               a_Chain_bcb(OpAbort, Info, NULL, NULL);               g_free(Info);            }            break;         case OpSend:            /* Send data */            if ((entry = Cache_entry_search(Info->LocalKey))) {               Cache_process_io(IORead, Data1);            } else {               a_Chain_bcb(OpAbort, Info, NULL, NULL);               g_free(Info);            }            break;         case OpEnd:            /* Unlink HTTP_Info */            a_Chain_del_link(Info, BCK);            g_free(Info);            Cache_process_io(IOClose, Data1);            break;         case OpAbort:            a_Chain_del_link(Info, BCK);            g_free(Info);            Cache_process_io(IOAbort, Data1);            break;         }      } else {  /* BCK */         switch (Op) {         case OpStart:            {            IOData_t *io2;            Info->LocalKey = Data2;            if ((entry = Cache_entry_search(Data2)))    // Is Data2 valid?               entry->CCCAnswer = Info;            /* Link IO to receive the answer */            io2 = a_IO_new(IORead, *(int*)Data1);            a_IO_set_buf(io2, NULL, IOBufLen);            io2->ExtData = Data2;       // We have it as LocalKey            a_Chain_link_new(Info, a_Cache_ccc, BCK, a_IO_ccc, 2, 2);            a_Chain_bcb(OpStart, Info, io2, NULL);            break;            }         case OpStop:            MSG(" Not implemented\n");            break;         case OpAbort:            Cache_entry_remove_raw(NULL, Info->LocalKey);            a_Chain_bcb(OpAbort, Info, NULL, NULL);            g_free(Info);            break;         }      }   }}static gbooleanCache_remove_hash_entry(gpointer key, gpointer value, gpointer user_data){   Cache_entry_free((CacheData_t *)value);   return TRUE;}/* * Memory deallocator (only called at exit time) */void a_Cache_freeall(void){   CacheClient_t *Client;   /* free the client queue */   while ( (Client = g_slist_nth_data(ClientQueue, 0)) )      Cache_client_dequeue(Client, NULLKey);   /* free the main cache */   /* Remove every cache entry */   g_hash_table_foreach_remove(CacheHash, (GHRFunc)Cache_remove_hash_entry,                               NULL);   /* Remove the cache hash */   g_hash_table_destroy(CacheHash);}

⌨️ 快捷键说明

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