source: abuse/branches/pd/macabuse/imlib/specs.c @ 636

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