@@ -247,6 +247,15 @@ typedef void(*plm_audio_decode_callback)
247247typedef void (* plm_buffer_load_callback )(plm_buffer_t * self , void * user );
248248
249249
250+ // Callback function for plm_buffer when it needs to seek
251+
252+ typedef void (* plm_buffer_seek_callback )(plm_buffer_t * self , size_t offset , void * user );
253+
254+
255+ // Callback function for plm_buffer when it needs to tell the position
256+
257+ typedef size_t (* plm_buffer_tell_callback )(plm_buffer_t * self , void * user );
258+
250259
251260// -----------------------------------------------------------------------------
252261// plm_* public API
@@ -477,6 +486,20 @@ plm_buffer_t *plm_buffer_create_with_filename(const char *filename);
477486plm_buffer_t * plm_buffer_create_with_file (FILE * fh , int close_when_done );
478487
479488
489+ // Create a buffer instance with custom callbacks for loading, seeking and
490+ // telling the position. This behaves like a file handle, but with user-defined
491+ // callbacks, useful for file handles that don't use the standard FILE API.
492+ // Setting the length and closing/freeing has to be done manually.
493+
494+ plm_buffer_t * plm_buffer_create_with_callbacks (
495+ plm_buffer_load_callback load_callback ,
496+ plm_buffer_seek_callback seek_callback ,
497+ plm_buffer_tell_callback tell_callback ,
498+ size_t length ,
499+ void * user
500+ );
501+
502+
480503// Create a buffer instance with a pointer to memory as source. This assumes
481504// the whole file is in memory. The bytes are not copied. Pass 1 to
482505// free_when_done to let plmpeg call free() on the pointer when plm_destroy()
@@ -1357,6 +1380,8 @@ struct plm_buffer_t {
13571380 int close_when_done ;
13581381 FILE * fh ;
13591382 plm_buffer_load_callback load_callback ;
1383+ plm_buffer_seek_callback seek_callback ;
1384+ plm_buffer_tell_callback tell_callback ;
13601385 void * load_callback_user_data ;
13611386 uint8_t * bytes ;
13621387 enum plm_buffer_mode mode ;
@@ -1377,6 +1402,8 @@ void plm_buffer_seek(plm_buffer_t *self, size_t pos);
13771402size_t plm_buffer_tell (plm_buffer_t * self );
13781403void plm_buffer_discard_read_bytes (plm_buffer_t * self );
13791404void plm_buffer_load_file_callback (plm_buffer_t * self , void * user );
1405+ void plm_buffer_seek_file_callback (plm_buffer_t * self , size_t offset , void * user );
1406+ size_t plm_buffer_tell_file_callback (plm_buffer_t * self , void * user );
13801407
13811408int plm_buffer_has (plm_buffer_t * self , size_t count );
13821409int plm_buffer_read (plm_buffer_t * self , int count );
@@ -1408,7 +1435,26 @@ plm_buffer_t *plm_buffer_create_with_file(FILE *fh, int close_when_done) {
14081435 self -> total_size = ftell (self -> fh );
14091436 fseek (self -> fh , 0 , SEEK_SET );
14101437
1411- plm_buffer_set_load_callback (self , plm_buffer_load_file_callback , NULL );
1438+ self -> load_callback = plm_buffer_load_file_callback ;
1439+ self -> seek_callback = plm_buffer_seek_file_callback ;
1440+ self -> tell_callback = plm_buffer_tell_file_callback ;
1441+ return self ;
1442+ }
1443+
1444+ plm_buffer_t * plm_buffer_create_with_callbacks (
1445+ plm_buffer_load_callback load_callback ,
1446+ plm_buffer_seek_callback seek_callback ,
1447+ plm_buffer_tell_callback tell_callback ,
1448+ size_t length ,
1449+ void * user
1450+ ) {
1451+ plm_buffer_t * self = plm_buffer_create_with_capacity (PLM_BUFFER_DEFAULT_SIZE );
1452+ self -> mode = PLM_BUFFER_MODE_FILE ;
1453+ self -> total_size = length ;
1454+ self -> load_callback = load_callback ;
1455+ self -> seek_callback = seek_callback ;
1456+ self -> tell_callback = tell_callback ;
1457+ self -> load_callback_user_data = user ;
14121458 return self ;
14131459}
14141460
@@ -1512,8 +1558,8 @@ void plm_buffer_rewind(plm_buffer_t *self) {
15121558void plm_buffer_seek (plm_buffer_t * self , size_t pos ) {
15131559 self -> has_ended = FALSE;
15141560
1515- if (self -> mode == PLM_BUFFER_MODE_FILE ) {
1516- fseek ( self -> fh , pos , SEEK_SET );
1561+ if (self -> seek_callback ) {
1562+ self -> seek_callback ( self , pos , self -> load_callback_user_data );
15171563 self -> bit_index = 0 ;
15181564 self -> length = 0 ;
15191565 }
@@ -1532,8 +1578,8 @@ void plm_buffer_seek(plm_buffer_t *self, size_t pos) {
15321578}
15331579
15341580size_t plm_buffer_tell (plm_buffer_t * self ) {
1535- return self -> mode == PLM_BUFFER_MODE_FILE
1536- ? ftell (self -> fh ) + (self -> bit_index >> 3 ) - self -> length
1581+ return self -> tell_callback
1582+ ? self -> tell_callback (self , self -> load_callback_user_data ) + (self -> bit_index >> 3 ) - self -> length
15371583 : self -> bit_index >> 3 ;
15381584}
15391585
@@ -1566,6 +1612,16 @@ void plm_buffer_load_file_callback(plm_buffer_t *self, void *user) {
15661612 }
15671613}
15681614
1615+ void plm_buffer_seek_file_callback (plm_buffer_t * self , size_t offset , void * user ) {
1616+ PLM_UNUSED (user );
1617+ fseek (self -> fh , offset , SEEK_SET );
1618+ }
1619+
1620+ size_t plm_buffer_tell_file_callback (plm_buffer_t * self , void * user ) {
1621+ PLM_UNUSED (user );
1622+ return ftell (self -> fh );
1623+ }
1624+
15691625int plm_buffer_has_ended (plm_buffer_t * self ) {
15701626 return self -> has_ended ;
15711627}
0 commit comments