source: abuse/trunk/src/imlib/specs.cpp @ 2

Last change on this file since 2 was 2, checked in by Sam Hocevar, 17 years ago
  • imported original 0.7.0 tarball
File size: 20.8 KB
Line 
1#include "image.hpp"
2#include "palette.hpp"
3#include "specs.hpp"
4#include <stdio.h>
5#include <stdlib.h>
6#include <ctype.h>
7#include <fcntl.h>
8#include "system.h"
9#include "jmalloc.hpp"
10#include <math.h>
11#include "dprint.hpp"
12#if (defined(__MACH__) || !defined(__APPLE__))
13#include <sys/types.h>
14#include <sys/stat.h>
15#endif
16
17#if (defined(__APPLE__) && !defined(__MACH__))
18extern char *macify_name(char *s);
19#endif
20
21char *spec_types[]={"Invalid type",             // 0
22                    "Color table",              // 1
23                    "Palette",                  // 2
24                    "Invalid Type",             // 3
25                    "Image",                    // 4
26                                        "Fore Tile",
27                    "Back Tile",
28                    "Character",
29                    "8 Morph",
30                    "16 Morph",
31                    "Grue objs",
32                    "Extern WAV",
33                    "DMX MUS",
34                    "Patched morph",
35                    "Normal file",
36                    "Compress1 file",
37                    "Vector Image",
38                    "Light list",
39                    "Grue fgmap",
40                    "Grue bgmap",
41                    "Data array",
42                    "Character2",
43                    "Particle",
44                    "Extern lcache"
45};
46
47
48int total_files_open=0;
49char spec_main_file[100];
50
51static char *spec_prefix=NULL;
52static char *save_spec_prefix=NULL;
53
54static jFILE spec_main_jfile((FILE*)0);
55static int spec_main_fd = -1;
56static long spec_main_offset = -1;
57static spec_directory spec_main_sd;
58
59static int fast_load_fd = -1;
60static int fast_load_mode = 0;
61
62void set_filename_prefix(char *prefix)
63{
64        if( spec_prefix )
65        {
66                jfree( spec_prefix );
67        }
68       
69        if( prefix )
70        {
71                spec_prefix = strcpy( (char *)jmalloc( strlen( prefix ) + 2, "prefix_name" ), prefix );
72                int len = strlen( prefix );
73                if( prefix[len - 1] != '\\' && prefix[len - 1] != '/')
74                {
75                        spec_prefix[len] = '/';
76                        spec_prefix[len + 1] = 0;
77                }
78        }
79        else
80        {
81                spec_prefix = NULL;
82        }
83}
84
85char *get_filename_prefix()
86{
87        return spec_prefix;
88}
89
90
91void set_save_filename_prefix(char *save_prefix)
92{
93        if( save_spec_prefix )
94        {
95                jfree( save_spec_prefix );
96        }
97
98        if( save_prefix )
99        {
100                int len = strlen( save_prefix );
101                save_spec_prefix = (char *)jmalloc( len + 1, "prefix_name" );
102                strcpy( save_spec_prefix, save_prefix );
103/* AK - Commented this out as it may cause problems
104                if( save_prefix[len - 1] != '\\' && save_prefix[len - 1] != '/' )
105                {
106                        save_spec_prefix[len] = '/';
107                        save_spec_prefix[len + 1] = '\0';
108                } */
109        }
110        else
111        {
112                save_spec_prefix = NULL;
113        }
114}
115
116char *get_save_filename_prefix()
117{
118  return save_spec_prefix;
119}
120
121int search_order=SPEC_SEARCH_OUTSIDE_INSIDE;
122
123static void (*no_space_handle_fun)()=NULL;
124
125void set_no_space_handler(void (*handle_fun)())
126{
127  no_space_handle_fun=handle_fun;
128}
129
130
131bFILE::bFILE()
132{
133  rbuf_size=8192;
134  rbuf=(unsigned char *)jmalloc(rbuf_size,"File read buffer");
135  rbuf_start=rbuf_end=0; 
136
137  wbuf_size=8192;
138  wbuf=(unsigned char *)jmalloc(wbuf_size,"File write buffer");
139  wbuf_end=0; 
140}
141
142bFILE::~bFILE()
143{
144  if (rbuf) jfree(rbuf);
145  flush_writes();
146  if (wbuf) jfree(wbuf);
147}
148
149int bFILE::flush_writes()
150{
151  if (wbuf_end!=0)
152  {
153    long ret=unbuffered_write(wbuf,wbuf_end);
154    if (ret!=wbuf_end && no_space_handle_fun)
155      no_space_handle_fun();
156     
157    wbuf_end=0;
158    return ret;
159  }
160  return 0;
161}
162
163int bFILE::read(void *buf, size_t count)       // returns number of bytes read, calls unbuffer_read
164{
165  if (!allow_read_buffering())
166    return unbuffered_read(buf,count);
167
168  int total_read=0,error=0;
169  if (!count) return 0;
170  while (count && !error)
171  {
172    if (rbuf_start<rbuf_end)
173    {
174      int avail_size=rbuf_end-rbuf_start;
175      int copy_size=avail_size>count ? count : avail_size;
176      memcpy(buf,rbuf+rbuf_start,copy_size);
177      buf=(void *)(((unsigned char *)buf)+copy_size);
178      rbuf_start+=copy_size;
179      if (rbuf_start>=rbuf_end)   
180      {
181                                if (rbuf_end!=rbuf_size)  // buffer wasn't full before so there is no way we can complete read
182                                  error=1;
183                                rbuf_start=rbuf_end=0;
184      }
185      total_read+=copy_size;
186      count-=copy_size;
187    } else
188    {
189      rbuf_end=unbuffered_read(rbuf,rbuf_size);
190      if (rbuf_end==0) error=1;
191      rbuf_start=0;
192    }
193  }
194  return total_read;
195}
196
197
198int bFILE::write(void *buf, size_t count)      // returns number of bytes written
199{
200  if (allow_write_buffering())
201  {
202    int total_written=0;
203    while (count)
204    {
205      int copy_size=wbuf_end+count<=wbuf_size ? count :  wbuf_size-wbuf_end;           
206      memcpy(wbuf+wbuf_end,buf,copy_size);
207      wbuf_end+=copy_size;
208      count-=copy_size;
209      buf=(void *)(((char *)buf)+copy_size);
210      if (wbuf_end==wbuf_size)
211        if (flush_writes()!=wbuf_size)
212          return total_written;
213     
214      total_written+=copy_size;     
215    }
216    return total_written;
217  } else
218  {
219    long ret=unbuffered_write(buf,count);
220    if (ret!=count && no_space_handle_fun)
221      no_space_handle_fun();
222  }
223  return 0;
224}
225
226int bFILE::seek(long offset, int whence) // whence=SEEK_SET, SEEK_CUR, SEEK_END, ret=0=success
227
228//    rbuf_start=rbuf_end=0;
229//    unbuffered_seek(offset,SEEK_SET);
230
231  long realpos=unbuffered_tell();
232  long curpos=realpos-rbuf_end+rbuf_start;
233  if (whence==SEEK_CUR) offset+=curpos;
234  else if (whence==SEEK_END) offset=file_size()-offset;
235
236  if (offset<realpos-rbuf_end || offset>=realpos)
237  {
238    rbuf_start=rbuf_end=0;
239    unbuffered_seek(offset,SEEK_SET);
240  } else 
241    rbuf_start=rbuf_end-(realpos-offset);
242  return 1;
243}
244
245int bFILE::tell()
246{
247  return unbuffered_tell()-rbuf_end+rbuf_start+
248         wbuf_end;    // if this a write file, add on how much we've written
249}
250
251int bFILE::allow_read_buffering() { return 1; }
252int bFILE::allow_write_buffering() { return 1; }
253
254void bFILE::set_read_buffer_size(long size)
255{
256  unbuffered_seek(tell(),SEEK_SET);
257  rbuf_start=rbuf_end=0;
258  if (rbuf)
259    jfree(rbuf);
260  rbuf_size=size;
261  rbuf=(unsigned char *)jmalloc(rbuf_size,"File buffer");
262}
263
264void set_spec_main_file(char *filename, int Search_order)
265{
266  dprintf("Specs : main file set to %s\n",filename);
267  strcpy(spec_main_file,filename);
268  search_order=Search_order;
269 
270#if (defined(__APPLE__) && !defined(__MACH__))
271  spec_main_jfile.open_external(filename,"rb",O_BINARY|O_RDONLY);
272  spec_main_fd = spec_main_jfile.get_fd();
273  spec_main_sd.startup(&spec_main_jfile);
274#else
275  spec_main_jfile.open_external(filename,"rb",O_RDONLY);
276  spec_main_fd = spec_main_jfile.get_fd();
277  spec_main_sd.startup(&spec_main_jfile);
278#endif
279}
280
281void fast_load_start_recording(char *filename)
282{
283#if (defined(__APPLE__) && !defined(__MACH__))
284  fast_load_fd = ::open(macify_name(filename),O_BINARY|O_CREAT|O_RDWR);
285#else
286  fast_load_fd = ::open(filename,O_CREAT|O_RDWR,S_IRWXU | S_IRWXG | S_IRWXO);
287#endif
288        fast_load_mode = 1;
289}
290
291void fast_load_stop_recording()
292{
293        fast_load_mode = 0;
294}
295
296void fast_load_start_reloading(char *filename)
297{
298#if (defined(__APPLE__) && !defined(__MACH__))
299  fast_load_fd = ::open(macify_name(filename),O_BINARY|O_RDONLY);
300#else
301  fast_load_fd = ::open(filename,O_RDONLY);
302#endif
303        fast_load_mode = 2;
304}
305
306void fast_load_stop_reloading()
307{
308        fast_load_mode = 0;
309}
310
311jFILE::jFILE(FILE *file_pointer)                       // assumes fp is at begining of file
312{
313  access=0;
314  fd=-1;
315  file_length=0;
316  start_offset=0;
317  flags=JFILE_CLONED;
318}
319
320void jFILE::open_external(char *filename, char *mode, int flags)
321{
322  int skip_size=0;
323  char tmp_name[200];
324  if (spec_prefix && filename[0] != '/')
325    sprintf(tmp_name,"%s%s",spec_prefix,filename);
326  else strcpy(tmp_name,filename);
327
328//  int old_mask=umask(S_IRWXU | S_IRWXG | S_IRWXO);
329#ifdef __WATCOMC__
330  flags|=O_BINARY;
331#endif
332  if (flags&O_WRONLY)
333  {
334    if ((flags&O_APPEND)==0)
335    {
336      skip_size=1;
337      int errval = unlink(tmp_name);
338    }
339
340    flags-=O_WRONLY;
341    flags|=O_CREAT|O_RDWR;
342
343#if (defined(__APPLE__) && !defined(__MACH__))
344    fd=open(macify_name(tmp_name),flags);
345#else
346    fd=open(tmp_name,flags,S_IRWXU | S_IRWXG | S_IRWXO);
347#endif
348  } else
349#if (defined(__APPLE__) && !defined(__MACH__))
350    fd=open(macify_name(tmp_name),flags);
351#else
352    fd=open(tmp_name,flags);
353#endif
354
355//  umask(old_mask);
356  if (fd>=0 && !skip_size)
357  {
358    file_length=lseek(fd,0,SEEK_END);
359    if ((flags&O_APPEND)==0)
360      lseek(fd,0,SEEK_SET);
361    else
362        current_offset = file_length;
363    start_offset=0;
364  } else
365  {
366    file_length=0;
367    start_offset=0;
368  }
369}
370
371
372class null_file : public bFILE     // this file type will use virtual opens inside of a spe
373{
374  public :
375  virtual int open_failure() { return 1; }
376  virtual int unbuffered_read(void *buf, size_t count)   { return 0; }
377  virtual int unbuffered_write(void *buf, size_t count)  { return 0; }
378  virtual int unbuffered_seek(long offset, int whence)   { return 0; }
379
380  virtual int unbuffered_tell() { return 0; }
381  virtual int file_size() { return 0; }
382  virtual ~null_file() { ; }
383} ;
384
385
386static bFILE *(*open_file_fun)(char *,char *)=NULL;
387int (*verify_file_fun)(char *,char *)=NULL;
388
389void set_file_opener(bFILE *(*open_fun)(char *, char *))
390{
391  open_file_fun=open_fun;
392}
393
394bFILE *open_file(char *filename, char *mode)
395{
396  if (!verify_file_fun || verify_file_fun(filename,mode))
397  {
398    if (open_file_fun)
399      return open_file_fun(filename,mode);
400    else return new jFILE(filename,mode);
401  } else return new null_file;
402}
403
404void jFILE::open_internal(char *filename, char *mode, int flags)
405{
406  int wr=0;
407  for (char *s=mode;*s;s++)
408    if (toupper(*s)=='A' || toupper(*s)=='W')
409      wr=1;
410
411  if (wr)
412    fd=-1;                 // only allow extern file openings for writing
413  else
414  {
415        fd = spec_main_fd;
416    if (fd>=0)                    // if we were able to open the main file, see if it's in there
417    {
418      start_offset=0;
419      spec_entry *se=spec_main_sd.find(filename);
420      if (se)   
421      {
422                                start_offset=se->offset;
423                                current_offset = 0;
424                                file_length=se->size;
425                                rbuf_start=rbuf_end=0;
426      } else
427      {
428                                close(fd);
429                                fd=-1;
430      }
431    } 
432  }
433}
434
435jFILE::jFILE(char *filename, char *access_string)      // same as fopen parameters
436{
437 flags=access=0; 
438 char *s=access_string;
439  for (;*s;s++)
440    if (toupper(*s)=='R') access=O_RDONLY;
441
442  for (s=access_string;*s;s++)
443    if (toupper(*s)=='W')     
444      if (access)
445        access=O_RDWR;
446      else access=O_WRONLY;
447
448  for (s=access_string;*s;s++)
449    if (toupper(*s)=='A')     
450      access|=O_APPEND|O_WRONLY;
451
452  file_length=start_offset=-1;
453  current_offset = 0;
454
455  fd=-1;
456  if (search_order==SPEC_SEARCH_OUTSIDE_INSIDE)
457    open_external(filename,access_string,access);
458
459  if (fd<0)
460    open_internal(filename,access_string,access);
461
462  if (fd<0 && search_order==SPEC_SEARCH_INSIDE_OUTSIDE)
463    open_external(filename,access_string,access);
464
465  total_files_open++;
466}
467
468jFILE::~jFILE()
469{
470  flush_writes();
471  if (fd>=0 && !(flags&JFILE_CLONED))
472  {
473    total_files_open--;
474    if (fd != spec_main_fd)
475            close(fd);
476  }
477}
478
479int jFILE::unbuffered_tell()
480{
481//      int ret = ::lseek(fd,0,SEEK_CUR) - start_offset;
482//      if (ret != current_offset)
483//              fprintf(stderr,"Bad tell %d\n",current_offset);
484        return current_offset;
485}
486
487int jFILE::unbuffered_read(void *buf, size_t count)
488{
489        long len;
490
491        if (fd == spec_main_fd)
492        {
493                switch (fast_load_mode)
494                {
495                case 0:
496                        if (current_offset+start_offset != spec_main_offset)
497                                spec_main_offset = lseek(fd, start_offset+current_offset, SEEK_SET);
498                       
499                        len = ::read(fd,(char*)buf,count);
500                        break;
501                case 1:
502                        if (current_offset+start_offset != spec_main_offset)
503                                spec_main_offset = lseek(fd, start_offset+current_offset, SEEK_SET);
504                       
505                        len = ::read(fd,(char*)buf,count);
506                        ::write(fast_load_fd,(char*)&len,sizeof(len));
507                        ::write(fast_load_fd,(char*)buf,count);
508                        break;
509                case 2:
510                        ::read(fast_load_fd,(char*)&len,sizeof(len));
511                        len = ::read(fast_load_fd,(char*)buf,len);
512                        break;
513                }
514               
515                spec_main_offset += len;
516        }
517        else
518        {
519                switch (fast_load_mode)
520                {
521                case 0:
522                len = ::read(fd,(char*)buf,count);
523                break;
524                case 1:
525                len = ::read(fd,(char*)buf,count);
526                        ::write(fast_load_fd,(char*)&len,sizeof(len));
527                        ::write(fast_load_fd,(char*)buf,count);
528                break;
529                case 2:
530                        ::read(fast_load_fd,(char*)&len,sizeof(len));
531                        len = ::read(fast_load_fd,(char*)buf,len);
532                        if (count != len)
533                                printf("short read! %ld:%ld\n",current_offset,len);
534                break;
535          }
536        }
537        current_offset += len;
538        return len;
539}
540
541int jFILE::unbuffered_write(void *buf, size_t count)
542{
543  long ret = ::write(fd,(char*)buf,count);
544        current_offset += ret;
545        return ret;
546}
547
548int jFILE::unbuffered_seek(long offset, int whence) // whence=SEEK_SET, SEEK_CUR, SEEK_END, ret=0=success
549{
550        long ret;
551       
552        if (fast_load_mode == 2)
553        {
554                switch (whence)
555                {
556    case SEEK_SET :
557        current_offset = start_offset+offset;
558        break;
559    case SEEK_END :
560        current_offset = start_offset+file_length-offset;
561        break;
562    case SEEK_CUR :
563        current_offset += offset;
564        break;
565    default:
566        ret = -1;
567        break;
568    }
569                return current_offset;
570        }
571       
572  switch (whence)
573  {
574    case SEEK_SET :
575    { ret = lseek(fd,start_offset+offset,SEEK_SET); } break;
576    case SEEK_END :
577    { ret = lseek(fd,start_offset+file_length-offset,SEEK_SET); } break;
578    case SEEK_CUR :
579    { ret = lseek(fd,offset,SEEK_CUR); } break;
580    default:
581        ret = -1;
582        break;
583  }
584  if (ret>=0)
585  {
586        current_offset = ret - start_offset;
587        if (spec_main_fd == fd)
588                spec_main_offset = ret;
589        return ret;
590  }
591  else
592          return -1;  // if a bad whence, then failure
593}
594
595
596unsigned char bFILE::read_byte()
597{ unsigned char x;
598  read(&x,1);
599  return x;
600}
601
602unsigned short bFILE::read_short()
603{
604  unsigned short x;
605  read(&x,2);
606  return int_to_local(x);
607}
608
609
610unsigned long bFILE::read_long()
611{
612  unsigned long x;
613  read(&x,4);
614  return long_to_local(x);
615}
616
617void bFILE::write_byte(unsigned char x)
618{
619  write(&x,1);
620}
621
622void bFILE::write_short(unsigned short x)
623{
624  x=int_to_local(x);
625  write(&x,2);
626}
627
628
629void bFILE::write_long(unsigned long x)
630{
631  x=long_to_local(x);
632  write(&x,4);
633}
634
635void bFILE::write_double(double x)
636{
637  double a;
638  write_long((long)(modf(x,&a)*(double)(1<<32-1)));
639  write_long((long)a);
640}
641
642double bFILE::read_double()
643{
644  long a,b;
645  a=read_long();
646  b=read_long();
647  return (double)b+a/(double)(1<<32-1);
648}
649
650spec_directory::~spec_directory()
651{
652
653  if (total)
654  {
655    jfree(data);
656    jfree(entries);
657  }
658}
659
660void spec_entry::print()
661{
662  printf("%15s%25s%8ld%8ld\n",spec_types[type],name,size,offset);
663}
664
665void spec_directory::calc_offsets()
666{
667  spec_entry **e;
668  int i;
669  long o=SPEC_SIG_SIZE+2;
670  if (total)
671  {
672    for (i=0,e=entries;i<total;i++,e++)          // calculate the size of directory info
673    {
674      o+=1+1+strlen((*e)->name)+1 +1 +8;
675    }
676
677    for (i=0,e=entries;i<total;i++,e++)          // calculate offset for each entry
678    {
679      (*e)->offset=o;
680      o+=(*e)->size;
681    }
682  }
683}
684
685spec_entry *spec_directory::find(char *name, int type)
686{
687  int i;
688  spec_entry **e;
689  for (i=0,e=entries;i<total;i++,e++)
690    if (!strcmp((*e)->name,name) && (*e)->type==type)
691      return (*e);
692  return NULL;
693}
694
695spec_entry *spec_directory::find(char *name)
696{
697  int i;
698  spec_entry **e;
699  for (i=0,e=entries;i<total;i++,e++)
700    if (!strcmp((*e)->name,name))
701      return (*e);
702  return NULL;
703}
704
705long spec_directory::find_number(char *name)
706{
707  int i;
708  spec_entry **e;
709  for (i=0,e=entries;i<total;i++,e++)
710    if (!strcmp((*e)->name,name))
711      return i;
712  return -1;
713}
714
715spec_entry *spec_directory::find(int type)
716{
717  int i;
718  spec_entry **e;
719  for (i=0,e=entries;i<total;i++,e++)
720    if ((*e)->type==type)
721      return (*e);
722  return NULL;
723}
724
725long spec_directory::type_total(int type)
726{
727  int i,x=0;
728  spec_entry **e;
729  for (i=0,e=entries;i<total;i++,e++)
730    if ((*e)->type==type) x++;
731  return x;
732}
733
734long spec_directory::find_number(int type)
735{
736  int i;
737  spec_entry **e;
738  for (i=0,e=entries;i<total;i++,e++)
739    if ((*e)->type==type)
740      return i;
741  return -1;
742}
743
744void spec_directory::print()
745{
746  spec_entry **se;
747  int i;
748  printf("[   Entry type   ][   Entry name   ][  Size  ][ Offset ]\n");
749  for (i=0,se=entries;i<total;i++,se++)
750    (*se)->print();
751}
752
753
754void spec_directory::startup(bFILE *fp)
755{
756  char buf[256];
757  fp->read(buf,8);
758  buf[9]=0;
759  size=0;
760  if (!strcmp(buf,SPEC_SIGNATURE))
761  {   
762    total=fp->read_short();   
763    entries=(spec_entry **)jmalloc(sizeof(spec_entry *)*total,"spec_directory::entries");
764    long start=fp->tell();
765
766    int i;
767    for (i=0;i<total;i++)
768    {           
769      fp->read(buf,2);
770      long entry_size=sizeof(spec_entry)+(unsigned char)buf[1];
771      entry_size=(entry_size+3)&(~3);
772      fp->read(buf,(unsigned char)buf[1]);
773      fp->read(buf,9);
774
775      size+=entry_size;
776    }
777    data=jmalloc(size,"spec_directory::data");
778    char *dp=(char *)data;
779    fp->seek(start,SEEK_SET);
780    for (i=0;i<total;i++)
781    {           
782      spec_entry *se=(spec_entry *)dp;
783      entries[i]=se;
784
785      unsigned char len,flags,type;
786      fp->read(&type,1);     
787      fp->read(&len,1);
788      se->type=type;
789      se->name=dp+sizeof(spec_entry);
790      fp->read(se->name,len);
791      fp->read(&flags,1);
792
793      se->size=fp->read_long();
794      se->offset=fp->read_long();
795      dp+=((sizeof(spec_entry)+len)+3)&(~3);
796    }
797  }
798  else
799  {
800    total=0;
801    data=NULL;
802    entries=NULL;
803  } 
804}
805
806
807spec_directory::spec_directory(bFILE *fp)
808{ startup(fp); }
809
810spec_directory::spec_directory(FILE *fp)
811{
812  jFILE jfp(fp);
813  startup(&jfp);
814}
815
816spec_directory::spec_directory()
817{
818  size=0;
819  total=0;
820  data=NULL;
821  entries=NULL;
822}
823
824/*
825spec_directory::spec_directory(char *filename)
826{
827  jFILE *fp;
828  if (filename)
829  {
830    fp=new jFILE(filename,"rb");
831    if (!fp->open_failure())
832      startup(fp);
833    else
834    {
835      total=0;
836      entries=NULL;
837    }
838    delete fp;
839  } else printf("NULL filename to spec_directory::spec_directory\n");
840}*/
841
842int write_string(bFILE *fp, char *st)
843{
844  unsigned char length=strlen(st)+1;
845  if (fp->write(&length,1)!=1) return 0;
846  if (fp->write(st,length)!=length) return 0;
847  return 1;
848}
849
850long spec_directory::data_start_offset()
851{
852  long i;
853  for (i=0;i<total;i++)
854    return entries[i]->offset;
855
856  return SPEC_SIG_SIZE+2;     // if no entries, then no data, but return where it would
857                              // start anyway
858}
859
860long spec_directory::data_end_offset()
861{
862  spec_entry **e;
863  long i;
864  for (i=total-1,e=entries;i>=0;i--,e++)
865    return (*e)->offset+(*e)->size;
866
867  return SPEC_SIG_SIZE+2;
868}
869
870int spec_directory::write(bFILE *fp)
871{
872
873  char sig[SPEC_SIG_SIZE];
874  unsigned char flags=0;
875  unsigned long offset,data_size;
876  spec_entry **e;
877  strcpy(sig,SPEC_SIGNATURE);
878
879  if (fp->write(sig,sizeof(sig))!=sizeof(sig))    return 0;
880  fp->write_short(total);
881
882
883  int i;
884  for (i=0,e=entries;i<total;i++,e++)
885  {
886    if (fp->write(&(*e)->type,1)!=1)                 return 0;
887    if (!write_string(fp,(*e)->name))                return 0;
888    flags=0;
889    if (fp->write(&flags,1)!=1)                     return 0;
890
891    data_size=long_to_intel((*e)->size);
892    if (fp->write((char *)&data_size,4)!=4)              return 0;
893    offset=long_to_intel((*e)->offset);
894    if (fp->write((char *)&offset,4)!=4)                  return 0;
895
896  }
897  return 1;
898}
899
900jFILE *spec_directory::write(char *filename)
901{
902  jFILE *fp;
903  fp=new jFILE(filename,"wb");
904  if (fp->open_failure()) { delete fp; return NULL; }
905  if (!write(fp))
906  {
907    delete fp;
908    return NULL;
909  } else return fp;
910
911}
912
913unsigned short read_short(FILE *fp)
914{
915  unsigned short x;
916  fread(&x,1,2,fp);
917  return int_to_local(x);
918}
919
920unsigned long read_long(FILE *fp)
921{
922  unsigned long x;
923  fread(&x,1,4,fp);
924  return (long)long_to_local(x);
925}
926void write_short(FILE *fp, unsigned short x)
927{
928  x=int_to_local(x);
929  fwrite(&x,1,2,fp);
930}
931
932void write_long(FILE *fp, unsigned long x)
933{
934  x=long_to_local(x);
935  fwrite(&x,1,4,fp);
936}
937
938unsigned char read_byte(FILE *fp) { return fgetc(fp)&0xff; }
939void write_byte(FILE *fp, unsigned char x) { fputc(x,fp); }
940
941unsigned short read_other_long(FILE *fp)
942{
943  unsigned long x;
944  fread(&x,1,4,fp);
945  return big_long_to_local(x);
946}
947
948unsigned long read_other_short(FILE *fp)
949{
950  unsigned short x;
951  fread(&x,1,2,fp);
952  return big_short_to_local(x);
953}
954
955
956void write_other_short(FILE *fp, unsigned short x)
957{
958  x=big_short_to_local(x);
959  fwrite(&x,1,2,fp);
960}
961
962void write_other_long(FILE *fp, unsigned long x)
963{
964  x=big_long_to_local(x);
965  fwrite(&x,1,4,fp);
966}
967
968void spec_directory::remove(spec_entry *e)
969{
970  int i;
971  for (i=0;i<total && entries[i]!=e;i++);            // find the entry in the array first
972 
973  if (entries[i]==e)                                 // make sre it was found
974  {
975    delete e;
976    total--;
977    for (;i<total;i++)                               // compact the pointer array
978      entries[i]=entries[i+1];
979    entries=(spec_entry **)jrealloc(entries,sizeof(spec_entry *)*total,"spec_directory::entries");
980  }
981  else
982    printf("Spec_directory::remove bad entry pointer\n");
983}
984
985
986
987void spec_directory::add_by_hand(spec_entry *e)
988{
989  total++;
990  entries=(spec_entry **)jrealloc(entries,sizeof(spec_entry *)*total,"spec_directory::entries");
991  entries[total-1]=e;
992}
993
994void spec_directory::delete_entries()   // if the directory was created by hand instead of by file
995{
996  int i;
997  for (i=0;i<total;i++)
998    delete entries[i];
999
1000  if (total)
1001    jfree(entries);
1002}
1003
1004
1005void note_open_fd(int fd, char *str)
1006{
1007  total_files_open++;
1008}
1009
1010void note_close_fd(int fd)
1011{
1012  total_files_open--;
1013}
1014
1015
1016void list_open_fds()
1017{
1018  printf("Total open dos fds=%d\n",total_files_open);
1019}
1020
Note: See TracBrowser for help on using the repository browser.