source: abuse/tags/pd/imlib/specs.c

Last change on this file 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.6 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#ifndef __POWERPC__
13#include <sys/types.h>
14#include <sys/stat.h>
15#endif
16
17#ifdef __POWERPC__
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_filename_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 __POWERPC__
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 __POWERPC__
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 __POWERPC__
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 && filename[0] != '/')
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 __POWERPC__
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 __POWERPC__
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;
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  size=0;
804  total=0;
805  data=NULL;
806  entries=NULL;
807}
808
809/*
810spec_directory::spec_directory(char *filename)
811{
812  jFILE *fp;
813  if (filename)
814  {
815    fp=new jFILE(filename,"rb");
816    if (!fp->open_failure())
817      startup(fp);
818    else
819    {
820      total=0;
821      entries=NULL;
822    }
823    delete fp;
824  } else printf("NULL filename to spec_directory::spec_directory\n");
825}*/
826
827int write_string(bFILE *fp, char *st)
828{
829  unsigned char length=strlen(st)+1;
830  if (fp->write(&length,1)!=1) return 0;
831  if (fp->write(st,length)!=length) return 0;
832  return 1;
833}
834
835long spec_directory::data_start_offset()
836{
837  spec_entry *e;
838  long o=0,i;
839  for (i=0;i<total;i++)
840    return entries[i]->offset;
841
842  return SPEC_SIG_SIZE+2;     // if no entries, then no data, but return where it would
843                              // start anyway
844}
845
846long spec_directory::data_end_offset()
847{
848  spec_entry **e;
849  long o=0,i;
850  for (i=total-1,e=entries;i>=0;i--,e++)
851    return (*e)->offset+(*e)->size;
852
853  return SPEC_SIG_SIZE+2;
854}
855
856int spec_directory::write(bFILE *fp)
857{
858
859  char sig[SPEC_SIG_SIZE];
860  unsigned short tentries;
861  unsigned char flags=0;
862  unsigned long offset,data_size;
863  spec_entry **e;
864  strcpy(sig,SPEC_SIGNATURE);
865
866  if (fp->write(sig,sizeof(sig))!=sizeof(sig))    return 0;
867  fp->write_short(total);
868
869
870  int i;
871  for (i=0,e=entries;i<total;i++,e++)
872  {
873    if (fp->write(&(*e)->type,1)!=1)                 return 0;
874    if (!write_string(fp,(*e)->name))                return 0;
875    flags=0;
876    if (fp->write(&flags,1)!=1)                     return 0;
877
878    data_size=long_to_intel((*e)->size);
879    if (fp->write((char *)&data_size,4)!=4)              return 0;
880    offset=long_to_intel((*e)->offset);
881    if (fp->write((char *)&offset,4)!=4)                  return 0;
882
883  }
884  return 1;
885}
886
887jFILE *spec_directory::write(char *filename)
888{
889  jFILE *fp;
890  fp=new jFILE(filename,"wb");
891  if (fp->open_failure()) { delete fp; return NULL; }
892  if (!write(fp))
893  {
894    delete fp;
895    return NULL;
896  } else return fp;
897
898}
899
900unsigned short read_short(FILE *fp)
901{
902  unsigned short x;
903  fread(&x,1,2,fp);
904  return int_to_local(x);
905}
906
907unsigned long read_long(FILE *fp)
908{
909  unsigned long x;
910  fread(&x,1,4,fp);
911  return (long)long_to_local(x);
912}
913void write_short(FILE *fp, unsigned short x)
914{
915  x=int_to_local(x);
916  fwrite(&x,1,2,fp);
917}
918
919void write_long(FILE *fp, unsigned long x)
920{
921  x=long_to_local(x);
922  fwrite(&x,1,4,fp);
923}
924
925unsigned char read_byte(FILE *fp) { return fgetc(fp)&0xff; }
926void write_byte(FILE *fp, unsigned char x) { fputc(x,fp); }
927
928unsigned short read_other_long(FILE *fp)
929{
930  unsigned long x;
931  fread(&x,1,4,fp);
932  return big_long_to_local(x);
933}
934
935unsigned long read_other_short(FILE *fp)
936{
937  unsigned short x;
938  fread(&x,1,2,fp);
939  return big_short_to_local(x);
940}
941
942
943void write_other_short(FILE *fp, unsigned short x)
944{
945  x=big_short_to_local(x);
946  fwrite(&x,1,2,fp);
947}
948
949void write_other_long(FILE *fp, unsigned long x)
950{
951  x=big_long_to_local(x);
952  fwrite(&x,1,4,fp);
953}
954
955void spec_directory::remove(spec_entry *e)
956{
957  int i;
958  for (i=0;i<total && entries[i]!=e;i++);            // find the entry in the array first
959 
960  if (entries[i]==e)                                 // make sre it was found
961  {
962    delete e;
963    total--;
964    for (;i<total;i++)                               // compact the pointer array
965      entries[i]=entries[i+1];
966    entries=(spec_entry **)jrealloc(entries,sizeof(spec_entry *)*total,"spec_directory::entries");
967  }
968  else
969    printf("Spec_directory::remove bad entry pointer\n");
970}
971
972
973
974void spec_directory::add_by_hand(spec_entry *e)
975{
976  total++;
977  entries=(spec_entry **)jrealloc(entries,sizeof(spec_entry *)*total,"spec_directory::entries");
978  entries[total-1]=e;
979}
980
981void spec_directory::delete_entries()   // if the directory was created by hand instead of by file
982{
983  int i;
984  for (i=0;i<total;i++)
985    delete entries[i];
986
987  if (total)
988    jfree(entries);
989}
990
991
992void note_open_fd(int fd, char *str)
993{
994  total_files_open++;
995}
996
997void note_close_fd(int fd)
998{
999  total_files_open--;
1000}
1001
1002
1003void list_open_fds()
1004{
1005  printf("Total open dos fds=%d\n",total_files_open);
1006}
1007
Note: See TracBrowser for help on using the repository browser.