@@ -150,11 +150,12 @@ hFILE *hfile_init_wrapper(size_t struct_size, hFILE* wrapper)
150150
151151 return & fp -> base ;
152152}
153+ static const struct hFILE_backend mem_backend ;
153154
154155void hfile_destroy (hFILE * fp )
155156{
156157 int save = errno ;
157- if (fp ) free (fp -> buffer );
158+ if (fp && fp -> backend != & mem_backend ) free (fp -> buffer );
158159 free (fp );
159160 errno = save ;
160161}
@@ -663,7 +664,7 @@ static hFILE *hopen_fd(const char *filename, const char *mode)
663664
664665static hFILE * hpreload_fd (const char * filename , const char * mode )
665666{
666- if (!strchr (mode , 'r' ))
667+ if (mode == NULL || !strchr (mode , 'r' ))
667668 {
668669 return NULL ;
669670 }
@@ -672,21 +673,13 @@ static hFILE *hpreload_fd(const char *filename, const char *mode)
672673 FILE * file = fopen (filename , mode );
673674 if (!file ) goto error ;
674675
675- fseek (file , 0 , SEEK_END );
676+ if ( fseek (file , 0 , SEEK_END ) != 0 ) goto error ;
676677 int len = ftell (file );
677678 fseek (file , 0 , SEEK_SET );
678679
679680 char * buffer = malloc (len );
680- if (buffer == NULL )
681- {
682- errno = ENOMEM ;
683- goto error ;
684- }
685- if (fread (buffer , 1 , len , file ) != len )
686- {
687- errno = EIO ;
688- goto error ;
689- }
681+ if (buffer == NULL ) goto error ;
682+ if (fread (buffer , 1 , len , file ) != len ) goto error ;
690683
691684 fp = (hFILE_fd * ) hfile_init_fixed (sizeof (hFILE_fd ), mode , buffer , len , len );
692685 if (fp == NULL ) goto error ;
@@ -798,6 +791,16 @@ static int cmp_prefix(const char *key, const char *s)
798791 return 0 ;
799792}
800793
794+ static hFILE * create_hfile_mem (char * buffer , const char * mode , size_t buf_filled , size_t buf_size )
795+ {
796+ hFILE_mem * fp = (hFILE_mem * ) hfile_init_fixed (sizeof (hFILE_mem ), mode , buffer , buf_filled , buf_size );
797+ if (fp == NULL )
798+ return NULL ;
799+
800+ fp -> base .backend = & mem_backend ;
801+ return & fp -> base ;
802+ }
803+
801804static hFILE * hopen_mem (const char * url , const char * mode )
802805{
803806 size_t length , size ;
@@ -821,13 +824,52 @@ static hFILE *hopen_mem(const char *url, const char *mode)
821824 if (buffer == NULL ) return NULL ;
822825 hts_decode_percent (buffer , & length , data );
823826 }
827+ hFILE * hf ;
824828
825- hFILE_mem * fp = (hFILE_mem * )
826- hfile_init_fixed (sizeof (hFILE_mem ), mode , buffer , length , size );
827- if (fp == NULL ) { free (buffer ); return NULL ; }
829+ if (!(hf = create_hfile_mem (buffer , mode , length , size ))){
830+ free (buffer );
831+ return NULL ;
832+ }
828833
829- fp -> base .backend = & mem_backend ;
830- return & fp -> base ;
834+ return hf ;
835+ }
836+
837+ hFILE * hopenv_mem (const char * filename , const char * mode , va_list args )
838+ {
839+ char * buffer = va_arg (args , char * );
840+ size_t sz = va_arg (args , size_t );
841+ va_end (args );
842+
843+ hFILE * hf ;
844+
845+ if (!(hf = create_hfile_mem (buffer , mode , sz , sz ))){
846+ free (buffer );
847+ return NULL ;
848+ }
849+
850+ return hf ;
851+ }
852+
853+ int hfile_mem_get_buffer (hFILE * file , char * * buffer , size_t * length ){
854+ if (file -> backend != & mem_backend ) {
855+ errno = EINVAL ;
856+ return -1 ;
857+ }
858+
859+ * buffer = file -> buffer ;
860+ * length = file -> buffer - file -> limit ;
861+
862+ return 0 ;
863+ }
864+
865+ int hfile_plugin_init_mem (struct hFILE_plugin * self )
866+ {
867+ // mem files are declared remote so they work with a tabix index
868+ static const struct hFILE_scheme_handler handler =
869+ {NULL , hfile_always_remote , "mem" , 2000 + 50 , hopenv_mem };
870+ self -> name = "mem" ;
871+ hfile_add_scheme_handler ("mem" , & handler );
872+ return 0 ;
831873}
832874
833875
@@ -908,44 +950,6 @@ static int init_add_plugin(void *obj, int (*init)(struct hFILE_plugin *),
908950 return 0 ;
909951}
910952
911- hFILE * hopenv_mem (const char * filename , const char * mode , va_list args )
912- {
913- char * buffer = va_arg (args , char * );
914- size_t sz = va_arg (args , size_t );
915- va_end (args );
916-
917- hFILE_mem * fp = (hFILE_mem * ) hfile_init_fixed (sizeof (hFILE_mem ), mode , buffer , sz , sz );
918-
919- fp -> base .backend = & mem_backend ;
920-
921- return & fp -> base ;
922- }
923-
924- int hfile_mem_get_buffer (hFILE * file , char * * buffer , size_t * length ){
925- if (file -> is_hFILE_wrapper )
926- file = ((hFILE_wrapper * )file )-> wrapper ;
927-
928- if (file -> backend != & mem_backend ) {
929- errno = EINVAL ;
930- return -1 ;
931- }
932-
933- * buffer = file -> buffer ;
934- * length = file -> buffer - file -> limit ;
935-
936- return 0 ;
937- }
938-
939- int hfile_plugin_init_mem (struct hFILE_plugin * self )
940- {
941- // mem files are declared remote so they work with a tabix index
942- static const struct hFILE_scheme_handler handler =
943- {NULL , hfile_always_remote , "mem" , 2000 + 50 , hopenv_mem };
944- self -> name = "mem" ;
945- hfile_add_scheme_handler ("mem" , & handler );
946- return 0 ;
947- }
948-
949953static void load_hfile_plugins ()
950954{
951955 static const struct hFILE_scheme_handler
0 commit comments