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

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