/* Copyright 1997 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/***************************************************/
/* File   : URLstat.c                              */
/*                                                 */
/* Purpose: Small source file to cope with the     */
/*          fetch status structures, 'urlstat'.    */
/*          Historically created when Fetch.c was  */
/*          split up on 17-Aug-97, and more than   */
/*          one source file suddenly needed to be  */
/*          able to deal with the structures.      */
/*                                                 */
/* Author : A.D.Hodgkinson                         */
/*                                                 */
/* History: 17-Aug-97: Created.                    */
/***************************************************/

#include <stdlib.h>
#include <string.h>

#include "HTMLLib.h" /* HTML library API, Which will include html2_ext.h, tags.h and struct.h */

#include "wimp.h"
#include "event.h"

#include "svcprint.h"
#include "Global.h"
#include "Utils.h"

#include "URLstat.h"

/* Statics */

static urlstat * fetch_list = NULL; /* Points to the base of the linked list of structures */

/*************************************************/
/* urlstat_add_entry()                           */
/*                                               */
/* Adds a fetch status (urlstat) structure to    */
/* the list of structures.                       */
/*                                               */
/* Initialises the contents with zero, and fills */
/* in the 'next' field (but nothing else).       */
/*                                               */
/* Parameters: A number to use in                */
/*             make_no_fetch_memory_error (see   */
/*             Utils.c) if the malloc for the    */
/*             structure fails;                  */
/*                                               */
/*             Pointer to a urlstat pointer, in  */
/*             which the address of the new      */
/*             structure is written (this is not */
/*             touched if the malloc fails).     */
/*                                               */
/* Assumes:    The urlstat address pointer may   */
/*             be NULL.                          */
/*************************************************/

_kernel_oserror * urlstat_add_entry(int report_num, urlstat ** new_urlstat)
{
  urlstat * up = NULL;

  #ifdef TRACE
    if (tl & (1u<<12)) Printf("urlstat_add_entry: malloc %d for 'urlstat' structure\n",sizeof(urlstat));
  #endif

  /* Allocate memory for the fetch */

  up = calloc(1, sizeof(urlstat));

  /* If the allocation failed, generate an error */

  if (!up) return make_no_fetch_memory_error(report_num);

  #ifdef TRACE
    malloccount += sizeof(urlstat);
    if (tl & (1u<<13)) Printf("** malloccount (urlstat_add_entry): \0211%d\0217\n",malloccount);
  #endif

  /* Otherwise, return the new structure's address */

  if (new_urlstat) *new_urlstat = up;

  /* Link in the new structure */

  up->next   = fetch_list;
  fetch_list = up;

  return NULL;
}

/*************************************************/
/* urlstat_remove_entry()                        */
/*                                               */
/* Removes an entry from the list of urlstat     */
/* structures, freeing memory allocated for it.  */
/*                                               */
/* Parameters: Pointer to the urlstat structure  */
/*             to remove.                        */
/*                                               */
/* Returns:    1 if successful, else 0.          */
/*************************************************/

int urlstat_remove_entry(urlstat * remove)
{
  urlstat *  up;
  urlstat ** pup;

  /* Point 'up' to the first item, and make 'pup' a pointer */
  /* to the pointer to the first item.                      */

  up  = fetch_list;
  pup = &fetch_list;

  /* Find the structure, but remember where the 'next' */
  /* pointer for the previous one was in 'pup'.        */

  while (up && up != remove) pup = &up->next, up = up->next;

  if (!up) return 0;

  /* Make the previous item - be that a urlstat's 'next' */
  /* pointer or the 'fetch_list' pointer - point to the  */
  /* structure after the current one. This, then, deals  */
  /* with the removed structure being first, middle,     */
  /* last, or the only structure in the list in passing. */

  *pup = up->next;

  /* If there is extra flex data attched, free it */

  #ifdef TRACE
    if (up->extradata)
    {
      if (tl & (1u<<12)) Printf("urlstat_remove_entry: flex_free block %p for 'extradata' field of 'urlstat' structure\n",&up->extradata);
      flexcount -= flex_size((flex_ptr) &up->extradata);
      if (tl & (1u<<14)) Printf("**   flexcount: %d\n",flexcount);
    }
  #endif

  if (up->extradata) flex_free((flex_ptr) &up->extradata);

  /* Free the block and exit */

  #ifdef TRACE
    if (tl & (1u<<12)) Printf("urlstat_remove_entry: free block %p holding 'urlstat' structure\n",up);
    malloccount -= sizeof(urlstat);
    if (tl & (1u<<13)) Printf("** malloccount (urlstat_remove_entry): \0212%d\0217\n",malloccount);
  #endif

  free(up);

  return 1;
}

/*************************************************/
/* urlstat_find_entry()                          */
/*                                               */
/* Returns the address of an entry in the list   */
/* of urlstat structures corresponding to a      */
/* given fetch session handle, or NULL if none   */
/* is found.                                     */
/*                                               */
/* Parameters: The session handle.               */
/*                                               */
/* Returns:    Pointer to a urlstat structure    */
/*             relevant to the session handle,   */
/*             or NULL if no relevant structure  */
/*             is found in the list.             */
/*************************************************/

urlstat * urlstat_find_entry(int session)
{
  urlstat * up = fetch_list;

  while (up && up->session != session) up = up->next;

  return up;
}