e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
1b10db2002-10-08Martin Nilsson 
22363a2002-05-30Per Hedbor #include "global.h" #include "bignum.h" #include "object.h" #include "interpret.h" #include "fdlib.h" #include "fd_control.h" #include <sys/stat.h> #include "shuffler.h"
67c6c42002-11-07Martin Nilsson /* Source: Pike-Stream
22363a2002-05-30Per Hedbor  * Argument: Stdio.File lookalike with read * callback support (set_read_callback) */ static struct program *callback_program; struct pf_source { struct source s; struct object *obj; struct object *cb_obj; struct pike_string *str;
eb94452019-06-11Stephen R. van den Berg  int available;
22363a2002-05-30Per Hedbor  void (*when_data_cb)( void *a ); void *when_data_cb_arg; size_t len, skip; }; struct callback_prog { struct pf_source *s; };
feb6822009-08-13Henrik Grubbström (Grubba) static void setup_callbacks( struct source *src )
22363a2002-05-30Per Hedbor {
feb6822009-08-13Henrik Grubbström (Grubba)  struct pf_source *s = (struct pf_source *)src;
eb94452019-06-11Stephen R. van den Berg  if( !s->available )
22363a2002-05-30Per Hedbor  { ref_push_object( s->cb_obj ); apply( s->obj, "set_read_callback", 1 ); pop_stack(); ref_push_object( s->cb_obj ); apply( s->obj, "set_close_callback", 1 ); pop_stack(); } }
feb6822009-08-13Henrik Grubbström (Grubba) static void remove_callbacks( struct source *src )
22363a2002-05-30Per Hedbor {
feb6822009-08-13Henrik Grubbström (Grubba)  struct pf_source *s = (struct pf_source *)src;
22363a2002-05-30Per Hedbor  push_int(0); apply( s->obj, "set_read_callback", 1 ); pop_stack(); push_int(0); apply( s->obj, "set_close_callback", 1 ); pop_stack(); }
eb94452019-06-11Stephen R. van den Berg static void frees(struct pf_source*s) { if (s->str) { free_string(s->str); s->str = 0; } }
22363a2002-05-30Per Hedbor 
feb6822009-08-13Henrik Grubbström (Grubba) static struct data get_data( struct source *src, off_t len )
22363a2002-05-30Per Hedbor {
feb6822009-08-13Henrik Grubbström (Grubba)  struct pf_source *s = (struct pf_source *)src;
eb94452019-06-11Stephen R. van den Berg  struct data res;
b2986f2002-07-05Per Hedbor 
eb94452019-06-11Stephen R. van den Berg  if (s->available) { if (!s->str) { s->s.eof = 1; res.len = 0; return res; }
22363a2002-05-30Per Hedbor  len = s->str->len;
eb94452019-06-11Stephen R. van den Berg  if (s->skip) { if (s->skip >= len) { frees(s); s->skip -= len; goto getmore;
22363a2002-05-30Per Hedbor  }
b2986f2002-07-05Per Hedbor  len -= s->skip;
22363a2002-05-30Per Hedbor  }
eb94452019-06-11Stephen R. van den Berg  if (s->len) { if (s->len < (size_t)len) len = s->len; s->len -= len; if (!s->len) s->s.eof = 1;
22363a2002-05-30Per Hedbor  }
eb94452019-06-11Stephen R. van den Berg  res.data = s->str->str + s->skip;
22363a2002-05-30Per Hedbor  res.len = len;
eb94452019-06-11Stephen R. van den Berg  if (s->available < 0) s->s.eof = 1; s->available = 0; } else { getmore:
22363a2002-05-30Per Hedbor  /* No data available, but there should be in the future (no EOF, nor * out of the range of data to send as specified by the arguments to * source_stream_make) */ res.len = -2;
ba96832019-06-14Stephen R. van den Berg  setup_callbacks(src);
eb94452019-06-11Stephen R. van den Berg  }
22363a2002-05-30Per Hedbor  return res; }
feb6822009-08-13Henrik Grubbström (Grubba) static void free_source( struct source *src )
22363a2002-05-30Per Hedbor {
eb94452019-06-11Stephen R. van den Berg  struct pf_source *s = (struct pf_source *)src;
feb6822009-08-13Henrik Grubbström (Grubba)  remove_callbacks( src );
eb94452019-06-11Stephen R. van den Berg  frees(s); free_object(s->cb_obj); free_object(s->obj);
22363a2002-05-30Per Hedbor } static void f_got_data( INT32 args ) { struct pf_source *s = ((struct callback_prog *)Pike_fp->current_object->storage)->s; remove_callbacks( (struct source *)s );
eb94452019-06-11Stephen R. van den Berg  if (args < 2 ||
017b572011-10-28Henrik Grubbström (Grubba)  TYPEOF(Pike_sp[-1]) != PIKE_T_STRING ||
22363a2002-05-30Per Hedbor  Pike_sp[-1].u.string->size_shift || Pike_sp[-1].u.string->len == 0) {
eb94452019-06-11Stephen R. van den Berg  s->available = -1;
22363a2002-05-30Per Hedbor  pop_n_elems(args); push_int(0); return; }
eb94452019-06-11Stephen R. van den Berg  frees(s); s->available = 1;
22363a2002-05-30Per Hedbor  s->str = Pike_sp[-1].u.string; Pike_sp--; pop_n_elems(args-1); push_int(0); if( s->when_data_cb ) s->when_data_cb( s->when_data_cb_arg ); }
feb6822009-08-13Henrik Grubbström (Grubba) static void set_callback( struct source *src, void (*cb)( void *a ), void *a )
22363a2002-05-30Per Hedbor {
feb6822009-08-13Henrik Grubbström (Grubba)  struct pf_source *s = (struct pf_source *)src;
22363a2002-05-30Per Hedbor  s->when_data_cb = cb; s->when_data_cb_arg = a; } struct source *source_pikestream_make( struct svalue *s, INT64 start, INT64 len ) { struct pf_source *res;
017b572011-10-28Henrik Grubbström (Grubba)  if( (TYPEOF(*s) != PIKE_T_OBJECT) ||
22363a2002-05-30Per Hedbor  (find_identifier("set_read_callback",s->u.object->prog)==-1) ) return 0;
13670c2015-05-25Martin Nilsson 
9c14f32014-04-27Martin Nilsson  res = calloc( 1, sizeof( struct pf_source ) ); if( !res ) return NULL;
22363a2002-05-30Per Hedbor  res->len = len; res->skip = start;
eb94452019-06-11Stephen R. van den Berg  res->available = 0;
22363a2002-05-30Per Hedbor  res->s.get_data = get_data; res->s.free_source = free_source; res->s.set_callback = set_callback; res->s.setup_callbacks = setup_callbacks; res->s.remove_callbacks = remove_callbacks; res->obj = s->u.object;
50ea682003-03-14Henrik Grubbström (Grubba)  add_ref(res->obj);
22363a2002-05-30Per Hedbor  res->cb_obj = clone_object( callback_program, 0 ); ((struct callback_prog *)res->cb_obj->storage)->s = res; return (struct source *)res; } void source_pikestream_exit( ) { free_program( callback_program ); } void source_pikestream_init( ) { start_new_program(); ADD_STORAGE( struct callback_prog );
362e4e2016-01-29Martin Nilsson  ADD_FUNCTION("`()", f_got_data, tFunc(tInt tStr,tVoid),0);
22363a2002-05-30Per Hedbor  callback_program = end_program(); }