Advertisement
Siapran

arch.c

Oct 2nd, 2011
379
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.16 KB | None | 0 0
  1. #include <tigcclib.h>
  2. #include "arch.h"
  3.  
  4. ARCH * afopen (const char *filename)
  5. {
  6.     FILE * f;
  7.     ARCH * arch = NULL;
  8.     if ((f = fopen (filename, "rb")) == NULL)
  9.         return NULL;
  10.  
  11.     if ((arch = (ARCH*)malloc(sizeof(ARCH))))
  12.     {
  13.         arch->archfile = f;
  14.         arch->sublvl = 0;
  15.         fseek(f,0,SEEK_SET);
  16.         arch->set = ftell(f);
  17.         fseek(f,0,SEEK_END);
  18.         arch->size = ftell(f) - arch->set;
  19.         arch->apos = 0;
  20.     }
  21.    
  22.     return arch;
  23. }
  24.  
  25. ARCH * aopen (ARCH * arch, const char * subfilename)
  26. {
  27.     ARCH *a, *b;
  28.     register unsigned short i, j;
  29.     unsigned char nbfile;
  30.     unsigned char filename[9];
  31.     unsigned short subdiroffset = 0;
  32.     unsigned char subdir[9];
  33.     short apos;
  34.     unsigned short filepos, filesize;
  35.  
  36.     a = (ARCH*)malloc(sizeof(ARCH));
  37.     if (a == NULL)
  38.         return NULL;
  39.     for (i = 0; i < strlen (subfilename); i++)
  40.     {
  41.         if (subfilename[i] == '\\') {subdiroffset = i; break;}
  42.     }
  43.    
  44.     if (i > 8)
  45.     {
  46.         free (a);
  47.         return NULL;
  48.     }
  49.  
  50.     strncpy (subdir, subfilename, i);
  51.     subdir[i] = 0;
  52.    
  53.     apos = arch->apos;
  54.     aseek (arch, 0, SEEK_SET);
  55.     aread (&nbfile, sizeof(unsigned char), 1, arch);
  56.    
  57.     for (i = 0; i < nbfile; i++)
  58.     {
  59.         aread (&filepos, sizeof(unsigned short), 1, arch);
  60.         aread (&filesize, sizeof(unsigned short), 1, arch);
  61.         for(j = 0; j < 8; j++)
  62.         {
  63.             aread (&(filename[j]), sizeof(unsigned char), 1, arch);
  64.             if (filename[j] == 0)
  65.                 break;
  66.         }
  67.         if (j == 8)
  68.             aseek (arch, 1, SEEK_CUR);
  69.  
  70.         filename[j] = 0;
  71.         if (strcmp (filename, subdir) == 0)
  72.         {
  73.             a->archfile = arch->archfile;
  74.             a->sublvl = arch->sublvl + 1;
  75.             a->set = filepos + arch->set;
  76.             a->apos = filepos + arch->set;
  77.             a->size = filesize;
  78.             arch->apos = apos;
  79.             if (subdiroffset)
  80.             {
  81.                 b = aopen (a, subfilename + subdiroffset + 1);
  82.                 free (a);
  83.                 a = b;
  84.             }
  85.             return a;
  86.         }
  87.     }
  88.     arch->apos = apos;
  89.     free (a);
  90.     return NULL;
  91.        
  92. }
  93.  
  94. void aclose (ARCH * arch)
  95. {
  96.     if (arch->sublvl == 0)
  97.         fclose (arch->archfile);
  98.     free (arch);
  99. }
  100.  
  101. unsigned short aread (void * ptr, unsigned short size, unsigned short n, ARCH * arch)
  102. {
  103.     unsigned short buffsize;
  104.     unsigned short retval;
  105.     unsigned short maxbuffsize = arch->set + arch->size - arch->apos;
  106.    
  107.     if ((size * n) <= maxbuffsize)
  108.     {
  109.         buffsize = size * n;
  110.         retval = n;
  111.     }
  112.     else
  113.     {
  114.         buffsize = maxbuffsize;
  115.         retval = maxbuffsize / size;
  116.     }
  117.     if (buffsize)
  118.     {
  119.         fseek (arch->archfile, arch->apos, SEEK_SET);
  120.         fread (ptr, buffsize, 1, arch->archfile);
  121.         arch->apos = arch->apos + buffsize;
  122.         return retval;
  123.     }
  124.    
  125.     return 0;
  126. }
  127.  
  128. short aseek (ARCH * arch, short offset, short whence)
  129. {
  130.     unsigned short newpos;
  131.    
  132.     switch (whence)
  133.     {
  134.         case SEEK_SET:
  135.             newpos = arch->set + offset;
  136.             if ((newpos >= arch->set) && (newpos < (arch->set + arch->size)))
  137.                 arch->apos = newpos;
  138.             else
  139.                 return 1;
  140.             break;
  141.         case SEEK_CUR:
  142.             newpos = arch->apos + offset;
  143.             if ((newpos >= arch->set) && (newpos < (arch->set + arch->size)))
  144.                 arch->apos = newpos;
  145.             else
  146.                 return 1;
  147.             break;
  148.         case SEEK_END:
  149.             newpos = arch->set + arch->size + offset;
  150.             if ((newpos >= arch->set) && (newpos < (arch->set + arch->size)))
  151.                 arch->apos = newpos;
  152.             else
  153.                 return 1;
  154.             break;
  155.         default: return 1;
  156.     }
  157.    
  158.     return 0;
  159. }
  160.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement