@@ -64,6 +64,7 @@ struct file_s
64
64
off_t length ;
65
65
off_t position ;
66
66
off_t offset ;
67
+ int ungetc ;
67
68
struct
68
69
{
69
70
off_t position ;
@@ -427,6 +428,9 @@ file_t *FS_FOpen (const char *filename, int flags)
427
428
file = (file_t * )Z_Malloc (sizeof (file_t ) + FS_BUFFER_SIZE + 64 );
428
429
memset (file , 0 , sizeof (file_t ) + FS_BUFFER_SIZE + 64 );
429
430
431
+ // ungetc invalidation
432
+ file -> ungetc = FS_EOF ;
433
+
430
434
// cache buffer
431
435
file -> buffer .ptr = (byte * )(((uintptr_t )file + sizeof (file_t ) + 63 ) & (~63 ));
432
436
@@ -636,14 +640,29 @@ off_t FS_FRead (file_t *file, const void *buffer, size_t size)
636
640
completed = 0 ;
637
641
remaining = (off_t )size ;
638
642
643
+ // the pushed back character by ungetc function
644
+ if (file -> ungetc != FS_EOF )
645
+ {
646
+ buf [completed ] = (byte )file -> ungetc ;
647
+
648
+ completed ++ ;
649
+ remaining -- ;
650
+
651
+ file -> ungetc = FS_EOF ;
652
+
653
+ if (remaining == 0 )
654
+ return completed ;
655
+
656
+ }
657
+
639
658
// check cache
640
659
if (file -> buffer .position < file -> buffer .length )
641
660
{
642
661
readlength = file -> buffer .length - file -> buffer .position ;
643
662
if (readlength > remaining )
644
663
readlength = remaining ;
645
664
646
- memcpy (buf , & file -> buffer .ptr [file -> buffer .position ], readlength );
665
+ memcpy (& buf [ completed ] , & file -> buffer .ptr [file -> buffer .position ], readlength );
647
666
file -> buffer .position += readlength ;
648
667
649
668
completed += readlength ;
@@ -789,6 +808,72 @@ int FS_FPrintf (file_t *file, const char *format, ...)
789
808
return FS_FWrite (file , outbuff , length );
790
809
}
791
810
811
+ /*
812
+ ====================
813
+ FS_Getc
814
+
815
+ Get the next character of a file
816
+ ====================
817
+ */
818
+ int FS_Getc (file_t * file )
819
+ {
820
+ char c ;
821
+
822
+ if (FS_FRead ( file , & c , 1 ) != 1 )
823
+ return FS_EOF ;
824
+
825
+ return c ;
826
+ }
827
+
828
+ /*
829
+ ====================
830
+ FS_UnGetc
831
+
832
+ Put a character back into the read buffer (only supports one character!)
833
+ ====================
834
+ */
835
+ int FS_UnGetc (file_t * file , byte c )
836
+ {
837
+ // If there's already a character waiting to be read
838
+ if (file -> ungetc != FS_EOF )
839
+ return FS_EOF ;
840
+
841
+ file -> ungetc = c ;
842
+ return c ;
843
+ }
844
+
845
+ /*
846
+ ====================
847
+ FS_Gets
848
+
849
+ Same as fgets
850
+ ====================
851
+ */
852
+ int FS_Gets (file_t * file , byte * buffer , size_t size )
853
+ {
854
+ int i , c ;
855
+
856
+ for (i = 0 ; i < size - 1 ; i ++ )
857
+ {
858
+ c = FS_Getc (file );
859
+ if (c == '\r' || c == '\n' || c < 0 )
860
+ break ;
861
+ buffer [i ] = c ;
862
+ }
863
+ buffer [i ] = 0 ;
864
+
865
+ // remove \n following \r
866
+ if (c == '\r' )
867
+ {
868
+ c = FS_Getc (file );
869
+
870
+ if (c != '\n' )
871
+ FS_UnGetc (file , (byte )c );
872
+ }
873
+
874
+ return c ;
875
+ }
876
+
792
877
/*
793
878
=================
794
879
FS_FSeek
@@ -815,6 +900,9 @@ int FS_FSeek (file_t *file, off_t offset, int whence)
815
900
if (offset < 0 || offset > file -> length )
816
901
return -1 ;
817
902
903
+ // ungetc invalidation
904
+ file -> ungetc = FS_EOF ;
905
+
818
906
// check cache
819
907
if (file -> position - file -> buffer .length <= offset && offset <= file -> position )
820
908
{
0 commit comments