sourcepawn/compiler/scmemfil.c
author David Anderson <dvander@alliedmods.net>
Wed Feb 25 20:07:12 2009 -0500 (2009-02-25)
changeset 2607 f3b8bbe17f85
parent 1952 b7aa2b626807
permissions -rw-r--r--
Backed out changeset fa286305bd3f
     1 /*  Pawn compiler
     2  *
     3  *  Routines to maintain a "text file" in memory.
     4  *
     5  *  Copyright (c) ITB CompuPhase, 2003-2006
     6  *
     7  *  This software is provided 'as-is', without any express or implied warranty.
     8  *  In no event will the authors be held liable for any damages arising from the
     9  *  use of this software.
    10  *
    11  *  Permission is granted to anyone to use this software for any purpose,
    12  *  including commercial applications, and to alter it and redistribute it
    13  *  freely, subject to the following restrictions:
    14  *
    15  *  1. The origin of this software must not be misrepresented; you must not
    16  *     claim that you wrote the original software. If you use this software in
    17  *     a product, an acknowledgment in the product documentation would be
    18  *     appreciated but is not required.
    19  *
    20  *  2. Altered source versions must be plainly marked as such, and must not be
    21  *     misrepresented as being the original software.
    22  *
    23  *  3. This notice may not be removed or altered from any source distribution.
    24  *
    25  *  Version: $Id$
    26  */
    27 
    28 #include <assert.h>
    29 #include <stdio.h>
    30 #include <stdlib.h>
    31 #include <string.h>
    32 #include "memfile.h"
    33 
    34 #if defined FORTIFY
    35   #include <alloc/fortify.h>
    36 #endif
    37 typedef memfile_t MEMFILE;
    38 #define tMEMFILE  1
    39 
    40 #include "sc.h"
    41 
    42 MEMFILE *mfcreate(const char *filename)
    43 {
    44   return memfile_creat(filename, 4096);
    45 }
    46 
    47 void mfclose(MEMFILE *mf)
    48 {
    49   memfile_destroy(mf);
    50 }
    51 
    52 int mfdump(MEMFILE *mf)
    53 {
    54   FILE *fp;
    55   int okay;
    56 
    57   assert(mf!=NULL);
    58   /* create the file */
    59   fp=fopen(mf->name, "wb");
    60   if (fp==NULL)
    61     return 0;
    62 
    63   okay=1;
    64   okay = okay & (fwrite(mf->base, mf->usedoffs, 1, fp)==(size_t)mf->usedoffs);
    65   
    66   fclose(fp);
    67   return okay;
    68 }
    69 
    70 long mflength(const MEMFILE *mf)
    71 {
    72   return mf->usedoffs;
    73 }
    74 
    75 long mfseek(MEMFILE *mf,long offset,int whence)
    76 {
    77   long length;
    78 
    79   assert(mf!=NULL);
    80   if (mf->usedoffs == 0)
    81     return 0L;          /* early exit: not a single byte in the file */
    82 
    83   /* find the size of the memory file */
    84   length=mflength(mf);
    85 
    86   /* convert the offset to an absolute position */
    87   switch (whence) {
    88   case SEEK_SET:
    89     break;
    90   case SEEK_CUR:
    91     offset+=mf->offs;
    92     break;
    93   case SEEK_END:
    94     assert(offset<=0);
    95     offset+=length;
    96     break;
    97   } /* switch */
    98 
    99   /* clamp to the file length limit */
   100   if (offset<0)
   101     offset=0;
   102   else if (offset>length)
   103     offset=length;
   104 
   105   /* set new position and return it */
   106   memfile_seek(mf, offset);
   107 
   108   return offset;
   109 }
   110 
   111 unsigned int mfwrite(MEMFILE *mf,const unsigned char *buffer,unsigned int size)
   112 {
   113   return (memfile_write(mf, buffer, size) ? size : 0);
   114 }
   115 
   116 unsigned int mfread(MEMFILE *mf,unsigned char *buffer,unsigned int size)
   117 {
   118   return memfile_read(mf, buffer, size);
   119 }
   120 
   121 char *mfgets(MEMFILE *mf,char *string,unsigned int size)
   122 {
   123   char *ptr;
   124   unsigned int read;
   125   long seek;
   126 
   127   assert(mf!=NULL);
   128 
   129   read=mfread(mf,(unsigned char *)string,size);
   130   if (read==0)
   131     return NULL;
   132   seek=0L;
   133 
   134   /* make sure that the string is zero-terminated */
   135   assert(read<=size);
   136   if (read<size) {
   137     string[read]='\0';
   138   } else {
   139     string[size-1]='\0';
   140     seek=-1;            /* undo reading the character that gets overwritten */
   141   } /* if */
   142 
   143   /* find the first '\n' */
   144   ptr=strchr(string,'\n');
   145   if (ptr!=NULL) {
   146     *(ptr+1)='\0';
   147     seek=(long)(ptr-string)+1-(long)read;
   148   } /* if */
   149 
   150   /* undo over-read */
   151   assert(seek<=0);      /* should seek backward only */
   152   if (seek!=0)
   153     mfseek(mf,seek,SEEK_CUR);
   154 
   155   return string;
   156 }
   157 
   158 int mfputs(MEMFILE *mf,const char *string)
   159 {
   160   unsigned int written,length;
   161 
   162   assert(mf!=NULL);
   163 
   164   length=strlen(string);
   165   written=mfwrite(mf,(unsigned char *)string,length);
   166   return written==length;
   167 }