#ifndef LEANSDR_GENERIC_H #define LEANSDR_GENERIC_H #include #include namespace leansdr { ////////////////////////////////////////////////////////////////////// // Simple blocks ////////////////////////////////////////////////////////////////////// // [file_reader] reads raw data from a file descriptor into a [pipebuf]. // If the file descriptor is seekable, data can be looped. template struct file_reader : runnable { file_reader(scheduler *sch, int _fdin, pipebuf &_out) : runnable(sch, _out.name), loop(false), fdin(_fdin), out(_out), pos(0) { } void run() { size_t size = out.writable() * sizeof(T); if ( ! size ) return; again: ssize_t nr = read(fdin, out.wr(), size); if ( nr < 0 ) fatal("read"); if ( !nr && !loop ) return; if ( ! nr ) { if ( sch->debug ) fprintf(stderr, "%s looping\n", name); off_t res = lseek(fdin, 0, SEEK_SET); if ( res == (off_t)-1 ) fatal("lseek"); goto again; } if ( nr % sizeof(T) ) fatal("partial read"); out.written(nr / sizeof(T)); } bool loop; private: int fdin; pipewriter out; off_t pos; }; // [file_writer] writes raw data from a [pipebuf] to a file descriptor. template struct file_writer : runnable { file_writer(scheduler *sch, pipebuf &_in, int _fdout) : runnable(sch, _in.name), in(_in), fdout(_fdout) { } void run() { int size = in.readable() * sizeof(T); if ( ! size ) return; int nw = write(fdout, in.rd(), size); if ( ! nw ) fatal("pipe"); if ( nw < 0 ) fatal("write"); if ( nw % sizeof(T) ) fatal("partial write"); in.read(nw/sizeof(T)); } private: pipereader in; int fdout; }; // [file_printer] writes data from a [pipebuf] to a file descriptor, // with printf-style formatting and optional scaling. template struct file_printer : runnable { file_printer(scheduler *sch, const char *_format, pipebuf &_in, int _fdout) : runnable(sch, _in.name), scale(1), in(_in), format(_format), fdout(_fdout) { } void run() { int n = in.readable(); T *pin=in.rd(), *pend=pin+n; for ( ; pin in; const char *format; int fdout; }; // [itemcounter] writes the number of input items to the output [pipebuf]. // [Tout] must be a numeric type. template struct itemcounter : runnable { itemcounter(scheduler *sch, pipebuf &_in, pipebuf &_out) : runnable(sch, "itemcounter"), in(_in), out(_out) { } void run() { if ( out.writable() < 1 ) return; unsigned long count = in.readable(); if ( ! count ) return; *out.wr() = count; in.read(count); out.written(1); } private: pipereader in; pipewriter out; }; } // namespace #endif // LEANSDR_GENERIC_H