@@ -404,7 +404,7 @@ off_t hseek(hFILE *fp, off_t offset, int whence)
404
404
{
405
405
off_t curpos , pos ;
406
406
407
- if (writebuffer_is_nonempty (fp )) {
407
+ if (writebuffer_is_nonempty (fp ) && fp -> mobile ) {
408
408
int ret = flush_buffer (fp );
409
409
if (ret < 0 ) return ret ;
410
410
}
@@ -615,6 +615,47 @@ static hFILE *hopen_fd(const char *filename, const char *mode)
615
615
return NULL ;
616
616
}
617
617
618
+ static hFILE * hpreload_fd (const char * filename , const char * mode )
619
+ {
620
+ if (!strchr (mode , 'r' ))
621
+ {
622
+ return NULL ;
623
+ }
624
+
625
+ hFILE_fd * fp = NULL ;
626
+ FILE * file = fopen (filename , mode );
627
+ if (!file ) goto error ;
628
+
629
+ fseek (file , 0 , SEEK_END );
630
+ int len = ftell (file );
631
+ fseek (file , 0 , SEEK_SET );
632
+
633
+ char * buffer = malloc (len );
634
+ if (buffer == NULL )
635
+ {
636
+ errno = ENOMEM ;
637
+ goto error ;
638
+ }
639
+ if (fread (buffer , 1 , len , file ) != len )
640
+ {
641
+ errno = EIO ;
642
+ goto error ;
643
+ }
644
+
645
+ fp = (hFILE_fd * ) hfile_init_fixed (sizeof (hFILE_fd ), mode , buffer , len , len );
646
+ if (fp == NULL ) goto error ;
647
+
648
+ fp -> fd = fileno (file );
649
+ fp -> is_socket = 0 ;
650
+ fp -> base .backend = & fd_backend ;
651
+ return & fp -> base ;
652
+
653
+ error :
654
+ if (file ) { int save = errno ; (void ) fclose (file ); errno = save ; }
655
+ hfile_destroy ((hFILE * ) fp );
656
+ return NULL ;
657
+ }
658
+
618
659
hFILE * hdopen (int fd , const char * mode )
619
660
{
620
661
hFILE_fd * fp = (hFILE_fd * ) hfile_init (sizeof (hFILE_fd ), mode , blksize (fd ));
@@ -821,6 +862,41 @@ static int init_add_plugin(void *obj, int (*init)(struct hFILE_plugin *),
821
862
return 0 ;
822
863
}
823
864
865
+ hFILE * hopenv_mem (const char * filename , const char * mode , va_list args )
866
+ {
867
+ char * buffer = va_arg (args , char * );
868
+ size_t sz = va_arg (args , size_t );
869
+ va_end (args );
870
+
871
+ hFILE_mem * fp = (hFILE_mem * ) hfile_init_fixed (sizeof (hFILE_mem ), mode , buffer , sz , sz );
872
+
873
+ fp -> base .backend = & mem_backend ;
874
+
875
+ return & fp -> base ;
876
+ }
877
+
878
+ int hfile_mem_get_buffer (hFILE * file , char * * buffer , size_t * length ){
879
+ if (file -> backend != & mem_backend ) {
880
+ errno = EINVAL ;
881
+ return -1 ;
882
+ }
883
+
884
+ * buffer = file -> buffer ;
885
+ * length = file -> buffer - file -> limit ;
886
+
887
+ return 0 ;
888
+ }
889
+
890
+ int hfile_plugin_init_mem (struct hFILE_plugin * self )
891
+ {
892
+ // mem files are declared remote so they work with a tabix index
893
+ static const struct hFILE_scheme_handler handler =
894
+ {NULL , hfile_always_remote , "mem" , 2000 + 50 , hopenv_mem };
895
+ self -> name = "mem" ;
896
+ hfile_add_scheme_handler ("mem" , & handler );
897
+ return 0 ;
898
+ }
899
+
824
900
static void load_hfile_plugins ()
825
901
{
826
902
static const struct hFILE_scheme_handler
@@ -833,6 +909,7 @@ static void load_hfile_plugins()
833
909
hfile_add_scheme_handler ("data" , & data );
834
910
hfile_add_scheme_handler ("file" , & file );
835
911
init_add_plugin (NULL , hfile_plugin_init_net , "knetfile" );
912
+ init_add_plugin (NULL , hfile_plugin_init_mem , "mem" );
836
913
837
914
#ifdef ENABLE_PLUGINS
838
915
struct hts_path_itr path ;
@@ -879,11 +956,25 @@ static hFILE *hopen_unknown_scheme(const char *fname, const char *mode)
879
956
return fp ;
880
957
}
881
958
959
+ static hFILE * hopenv_unknown_scheme (const char * fname , const char * mode , va_list args )
960
+ {
961
+ char * method_type = va_arg (args , char * );
962
+ va_end (args );
963
+ if (!strcmp (method_type , "preload" )){
964
+ errno = EPROTONOSUPPORT ;
965
+ return NULL ;
966
+ }
967
+
968
+ hFILE * fp = hpreload_fd (fname , mode );
969
+ if (fp == NULL && errno == ENOENT ) errno = EPROTONOSUPPORT ;
970
+ return fp ;
971
+ }
972
+
882
973
/* Returns the appropriate handler, or NULL if the string isn't an URL. */
883
974
static const struct hFILE_scheme_handler * find_scheme_handler (const char * s )
884
975
{
885
976
static const struct hFILE_scheme_handler unknown_scheme =
886
- { hopen_unknown_scheme , hfile_always_local , "built-in" , 0 };
977
+ { hopen_unknown_scheme , hfile_always_local , "built-in" , 2000 + 50 , hopenv_unknown_scheme };
887
978
888
979
char scheme [12 ];
889
980
int i ;
0 commit comments