/*

File: support.c
Author: Neil Cafferkey
Copyright (C) 2001-2002 Neil Cafferkey

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.

*/


#include "handler_protos.h"



/****i* ram.handler/SetString **********************************************
*
*   NAME
*	SetString --
*
*   SYNOPSIS
*	block_diff = SetString(field,new_str)
*
*	PINT SetString(TEXT **,TEXT *);
*
*   FUNCTION
*
*   INPUTS
*
*   RESULT
*
*   EXAMPLE
*
*   NOTES
*
*   BUGS
*
*   SEE ALSO
*
****************************************************************************
*
*/

PINT SetString(TEXT **field,const TEXT *new_str)
{
   LONG error;
   UPINT length;
   STRPTR str_copy,old_str;
   PINT block_diff;

   /* Allocate new string */

   error=0;
   length=0;
   block_diff=0;
   str_copy=NULL;
   if(new_str!=NULL)
   {
      length=StrSize(new_str);
      if(length>1)
      {
         str_copy=AllocMem(length,MEMF_ANY);
         if(str_copy!=NULL)
         {
            CopyMem(new_str,str_copy,length);
         }
         else
            error=IoErr();
      }
      else
         length=0;
   }

   if(error==0)
   {
      /* Deallocate old string */

      if(length>0)
         block_diff=MEMBLOCKS(length);
      length=0;
      old_str=*field;
      if(old_str!=NULL)
      {
         length=StrLen(old_str)+1;
         FreeMem(old_str,length);
         block_diff-=MEMBLOCKS(length);
      }

      /* Store new string */

      *field=str_copy;
   }

   /* Store secondary error and return difference in block utilisation */

   SetIoErr(error);
   if(error!=0)
      block_diff=-1;
   return block_diff;
}



/****i* ram.handler/SwapStrings ********************************************
*
*   NAME
*	SwapStrings --
*
*   SYNOPSIS
*	block_diff = SwapStrings(field1,field2)
*
*	PINT SetString(STRPTR *,STRPTR *);
*
*   FUNCTION
*
*   INPUTS
*
*   RESULT
*
*   EXAMPLE
*
*   NOTES
*
*   BUGS
*
*   SEE ALSO
*
****************************************************************************
*
*/

PINT SwapStrings(TEXT **field1,TEXT **field2)
{
   STRPTR str1,str2;
   PINT block_diff;

   block_diff=0;

   str1=*field1;
   if(str1!=NULL)
      block_diff=MEMBLOCKS(StrSize(str1));

   str2=*field2;
   if(str2!=NULL)
      block_diff-=MEMBLOCKS(StrSize(str2));

   *field1=str2;
   *field2=str1;

   /* Return difference in block utilisation */

   return block_diff;
}



/****i* ram.handler/StrLen *************************************************
*
*   NAME
*	StrLen --
*
*   SYNOPSIS
*	length = StrLen(s)
*
*	UPINT StrLen(TEXT *);
*
*   FUNCTION
*
*   INPUTS
*
*   RESULT
*
*   EXAMPLE
*
*   NOTES
*
*   BUGS
*
*   SEE ALSO
*
****************************************************************************
*
*/

UPINT StrLen(const TEXT *s)
{
   const TEXT *p;

   for(p=s;*p!='\0';p++);
   return p-s;
}



/****i* ram.handler/StrSize ************************************************
*
*   NAME
*	StrLen --
*
*   SYNOPSIS
*	size = StrSize(s)
*
*	UPINT StrSize(TEXT *);
*
*   FUNCTION
*
*   INPUTS
*
*   RESULT
*
*   EXAMPLE
*
*   NOTES
*
*   BUGS
*
*   SEE ALSO
*
****************************************************************************
*
*/

UPINT StrSize(const TEXT *s)
{
   const TEXT *p;

   for(p=s;*p!='\0';p++);
   return p-s+1;
}



/****i* ram.handler/FindNameNoCase *****************************************
*
*   NAME
*	FindNameNoCase --
*
*   SYNOPSIS
*	node = FindNameNoCase(start,name)
*
*	struct Node *FindNameNoCase(struct List *,TEXT *);
*
*   FUNCTION
*
*   INPUTS
*
*   RESULT
*
*   EXAMPLE
*
*   NOTES
*
*   BUGS
*
*   SEE ALSO
*
****************************************************************************
*
*/

struct Node *FindNameNoCase(struct List *start,const TEXT *name)
{
   struct Node *node,*next_node,*matching_node;
   STRPTR node_name;

   matching_node=NULL;
   node=start->lh_Head;

   while(node!=NULL)
   {
      next_node=node->ln_Succ;
      if(next_node!=NULL)
      {
         node_name=node->ln_Name;
         if(node_name!=NULL)
            if(Stricmp(name,node_name)==0)
            {
               matching_node=node;
               next_node=NULL;
            }
      }
      node=next_node;
   }

   return matching_node;
}



/****i* ram.handler/MyMakeDosEntry *****************************************
*
*   NAME
*	MyMakeDosEntry --
*
*   SYNOPSIS
*	dos_entry = MyMakeDosEntry(name,type)
*
*	struct DosList *MyMakeDosEntry(TEXT *,LONG);
*
*   FUNCTION
*
*   INPUTS
*
*   RESULT
*
*   EXAMPLE
*
*   NOTES
*
*   BUGS
*
*   SEE ALSO
*
****************************************************************************
*
*/

struct DosList *MyMakeDosEntry(const TEXT *name,LONG type)
{
   struct DosList *entry;
   LONG error;

   error=0;
   entry=AllocMem(sizeof(struct DosList),MEMF_CLEAR|MEMF_PUBLIC);

   if(entry!=NULL)
   {
      if(!MyRenameDosEntry(entry,name))
         error=IoErr();
      entry->dol_Type=type;
   }
   else
      error=IoErr();

   if(error!=0)
   {
      MyFreeDosEntry(entry);
      entry=NULL;
   }

   SetIoErr(error);
   return entry;
}



/****i* ram.handler/MyFreeDosEntry *****************************************
*
*   NAME
*	MyFreeDosEntry --
*
*   SYNOPSIS
*	MyFreeDosEntry(entry)
*
*	VOID MyFreeDosEntry(struct DosList *);
*
*   FUNCTION
*
*   INPUTS
*
*   RESULT
*
*   EXAMPLE
*
*   NOTES
*
*   BUGS
*
*   SEE ALSO
*
****************************************************************************
*
*/

VOID MyFreeDosEntry(struct DosList *entry)
{
   if(entry!=NULL)
   {
      MyRenameDosEntry(entry,NULL);
      FreeMem(entry,sizeof(struct DosList));
   }

   return;
}



/****i* ram.handler/MyRenameDosEntry ***************************************
*
*   NAME
*	MyRenameDosEntry --
*
*   SYNOPSIS
*	success = MyRenameDosEntry(entry,name)
*
*	BOOL MyRenameDosEntry(struct DosList *,TEXT *);
*
*   FUNCTION
*
*   INPUTS
*
*   RESULT
*
*   EXAMPLE
*
*   NOTES
*
*   BUGS
*
*   SEE ALSO
*
****************************************************************************
*
*/

BOOL MyRenameDosEntry(struct DosList *entry,const TEXT *name)
{
   LONG error;
   UPINT length;
   STRPTR name_copy,old_name;

   /* Allocate new string */

   error=0;
   name_copy=NULL;
   if(name!=NULL)
   {
      length=StrLen(name);
      name_copy=AllocMem(length+2,MEMF_PUBLIC);
      if(name_copy!=NULL)
      {
         CopyMem(name,name_copy+1,length+1);
         *name_copy=length;
      }
      else
         error=IoErr();
   }

   /* Deallocate old string */

   if(error==0)
   {
      old_name=BADDR(entry->dol_Name);
      if(old_name!=NULL)
         FreeMem(old_name,*old_name+2);
      entry->dol_Name=MKBADDR(name_copy);
   }

   /* Store error code and return success flag */

   SetIoErr(error);
   return error==0;
}



