/* misc.c - misc support functions.
   Copyright (C) 1991, 1992, 1993 Kristian Nielsen.

   This file is part of XFH, the compressing file system handler.

   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., 675 Mass Ave, Cambridge, MA 02139, USA.            */

#include "CFS.h"

#include <string.h>
#include "dossupport.h"

/* Allocate (CSTR) copy of BSTR. Result is modifyable. */
/* (NOTE: 'bstr' is a BPTR, not UBYTE *). */
char *copybstr(BSTR bstr){
   UBYTE buf[256];
   
   if(!bstr) return NULL;
   bstr2c(bstr,buf);
   return copystr(buf);
}

/* Allocate copy of C string. */
char *copystr(char *str){
   char *p;
   
  if(!str) return NULL;
  if(!(p=dosalloc(strlen(str)+1))) return NULL;
  strcpy(p,str);
  return p;
}

/* Free allocated string. */
void freestr(char *str){
   dosfree(str);
}


/* "Safe" (bounded-buffer) versions of bstr2cinplace() / cstr2binplace(). */
/* Only does their stuff if string seems a valid BSTR. */
char *safebstr2cinplace(UBYTE *pp, int buflen){
   register int len;
   register UBYTE *p;
   
   len = *pp;
   if(len < buflen){
      for( p=pp; len--; p++ ) p[0] = p[1];
      *p = '\0';
   }
   return (char *)pp;
}


BSTR safecstr2binplace(char *pp, int buflen){
   register int len;
   register char c,d;
   register char *p;
   
   for(len=0,p=pp; len<buflen && *p; len++,p++);
   if(len<buflen){
      for( c=len,p=pp; len--; p++ ){
         d=*p;
         *p=c;
         c=d;
      }
      *p=c;
   }
   return (BSTR)((ULONG)pp>>2);
}


/* ank - give the error ERROR_ACTION_NOT_KNOWN. */
LONG ank( glb glob, ... ){
   glob->ioerr = ERROR_ACTION_NOT_KNOWN;
   return 0L;
}

/* ank_fail - give the error ERROR_ACTION_NOT_KNOWN, but fail with -1L. */
LONG ank_fail( glb glob, ... ){
   glob->ioerr = ERROR_ACTION_NOT_KNOWN;
   return -1L;
}

/* own - give the error ERROR_OBJECT_WRONG_TYPE. */
LONG owt( glb glob, ... ){
   glob->ioerr = ERROR_OBJECT_WRONG_TYPE;
   return 0L;
}

/* abs_seek_pos - get absolute seek pos from pos/offset pair. */
LONG abs_seek_pos( LONG currentpos, LONG filelen, LONG pos, LONG offset ){
   
   switch(offset){
      case OFFSET_BEGINNING:
         return pos;
      case OFFSET_CURRENT:
         return currentpos + pos;
      case OFFSET_END:
         return filelen + pos;
      default:
         debug(("Error: abs_seek_pos: Bad offset value for Seek(): %ld\n",offset));
         return -1L;
   }
}


/* Get size of file from UFS filehandle. Return -1 if error. */
LONG xFileSizeXfh( glb glob, struct FileHandle *xfh ){
   LONG oldpos;
   LONG size;
   
   oldpos = xSeek( glob, xfh, 0, OFFSET_END );
   if( oldpos == -1L ){
      debug(("Error: xFileSizeXfh(): Cannot obtain size.\n"));
      return -1L;
   }
   size = xSeek( glob, xfh, oldpos, OFFSET_BEGINNING );
   if( size == -1L ){
      debug(("Error: xFileSizeXfh(): Cannot obtain size.\n"));
   }
   return size;
}

/* End of misc.c */
