bpipe_dump.c
This program will dump the contents of an input BPipe
stream
(on stdin
) to stdout
, formatting it for human comprehension.
/* --8<--8<--8<--8<-- * * Copyright (C) 2006 Smithsonian Astrophysical Observatory * * This file is part of bpipe * * bpipe is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * bpipe is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301, USA * * -->8-->8-->8-->8-- */ #include <stddef.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <bpipe/bpipe.h> #include <bpipe/datatypes.h> /* simple print error and exit routine */ #define error(string) \ do { \ fprintf( stderr, __FILE__ " %d: %s\n", __LINE__, string ); \ exit( EXIT_FAILURE ); \ } while (0) /* -----------------------------------------------------------------------*/ /* forward definitions */ void print_matrix( BPMatrix *matrix, char *buf ); void * print_data( char *prefix, BPDataType type, BPMatrix *matrix, void *data, size_t level ); /* -----------------------------------------------------------------------*/ int main (int argc, char *argv[]) { BPipe *bpipe; DpktField *dpktf; BPMatrix *matrix; void *data; size_t index; void *last; char *name; size_t dpkt_core_size, n; /* create BPipe object */ if ( NULL == ( bpipe = bpipe_new( ) ) ) error( bpipe_strerror( bpipe_errno ) ); /* attach standard input to the BPipe */ if ( bpipe_input( bpipe, "stdin" ) ) error( bpipe_strerror( bpipe_errno ) ); /* step through header fields and print out their definitions and data */ printf( "header fields:\n" ); /* last is used by bpipe_hdrf_next to keep track of where it is */ last = NULL; /* initialize it for first time through */ /* loop until there are no more header fields available */ while ( bpipe_hdrf_next( bpipe, &name, &index, &last ) ) { char buf[1024]; /* extract the data type and a pointer to the data. these should be valid since we've been handed name and index by bpipe_hdrf_next */ BPDataType type = bpipe_hdrf_type( bpipe, name, index ); void * data = bpipe_hdrf_data( bpipe, name, index ); if ( bpipe_errno != BPNOERROR ) error( bpipe_strerror( bpipe_errno ) ); /* extract matrix spec. since it's copying the matrix, there's a possibility that we're out of memory, which we check for */ if ( NULL == (matrix = bpipe_hdrf_matrix ( bpipe, name, index ) ) ) error( bpipe_strerror( bpipe_errno ) ); /* generate the field definition. this is used to prefix the data output */ sprintf(buf, "%s-%lu", name, (unsigned long) index ); print_matrix( matrix, buf ); strcat( buf, ": " ); /* dump the data */ /* if it's a one dimensional character array, assume that it's a C string */ if ( BPDType_char == type && matrix->nd == 1 ) printf( "%s%s\n", buf, (char*) data ); else print_data( buf, type, matrix, data, matrix->nd - 1 ); /* we're responsible for deleting the matrix spec returned by bpipe_hdrf_matrix */ bpipe_matrix_delete( matrix ); } /* now print out the data packet field definitions */ printf( "\ndata fields:\n" ); last = NULL; /* initialize it for first time through */ while (( dpktf = bpipe_dpktf_next( bpipe, &last ) )) { char buf[1024]; /* extract matrix spec. since it's copying the matrix, there's a possibility that we're out of memory, which we check for */ if ( NULL == (matrix = bpipe_dpktf_matrix( dpktf, BPDSite_CORE, NULL ) ) ) error( bpipe_strerror( bpipe_errno ) ); /* print out the definition */ strcpy( buf, bpipe_dpktf_name( dpktf ) ); print_matrix( matrix, buf ); puts( buf ); /* we're responsible for deleting the matrix spec returned by bpipe_dpktf_matrix */ bpipe_matrix_delete( matrix ); } /* we haven't manipulated any fields, but still must map the data packet images to get the size of the core image */ /* since we haven't done anything, bpipe_map should only fail if it runs out of memory. note that its possible that there are no data packet fields, in which case a return of zero isn't an error */ if ( 0 == ( dpkt_core_size = bpipe_map( bpipe ) ) && bpipe_errno != BPNOERROR ) error( bpipe_strerror( bpipe_errno ) ); /* if there are no data packets, there's not much left to do */ if ( dpkt_core_size == 0 ) { bpipe_delete( bpipe ); return EXIT_SUCCESS; } /* space for instance of data packet */ if ( NULL == (data = malloc( dpkt_core_size )) ) error( "unable to allocate data packet" ); /* loop through data packets */ n = 0; while( bpipe_read_dpkts( bpipe, data, (size_t) 1 ) ) { n++; printf( "\ndata packet %lu:\n", (unsigned long) n ); last = NULL; while (( dpktf = bpipe_dpktf_next( bpipe, &last ) )) { char buf[1024]; /* for speed, we could have saved these while printing the field definitions above, but these are pretty cheap calls */ void *dpktf_data = bpipe_dpktf_data( dpktf, data ); BPDataType type = bpipe_dpktf_type( dpktf ); if ( bpipe_errno != BPNOERROR ) error( bpipe_strerror( bpipe_errno ) ); /* this call is expensive, as it must copy the matrix. ordinarily one would do this outside of the read loop and store the values */ if ( NULL == (matrix = bpipe_dpktf_matrix( dpktf, BPDSite_CORE, NULL ) ) ) error( bpipe_strerror( bpipe_errno ) ); strcpy( buf, bpipe_dpktf_name( dpktf ) ); print_matrix( matrix, buf ); strcat( buf, ": " ); if ( BPDType_char == type && matrix->nd == 1 ) printf( "%s%s\n", buf, (char*) dpktf_data ); else print_data( buf, type, matrix, dpktf_data, matrix->nd - 1 ); /* we're responsible for deleting the matrix spec returned by bpipe_dpktf_matrix */ bpipe_matrix_delete( matrix ); } } /* we'll get an error out of bpipe_read_dpkts if something's gone awry. bpipe_errno should have been equal to BPNOERROR when entering the above loop */ if ( bpipe_errno != BPNOERROR ) error( bpipe_strerror( bpipe_errno ) ); bpipe_delete(bpipe); free( data ); return EXIT_SUCCESS; } /* print out matrix spec */ void print_matrix( BPMatrix *matrix, char *buf ) { int i; for ( i = 0 ; i < matrix->nd ; i++ ) sprintf(buf + strlen( buf ), "[%lu]", (unsigned long) matrix->extent[i] ); } /* recursive N-dimensional matrix data print routine */ void * print_data( char *prefix, BPDataType type, BPMatrix *matrix, void *data, size_t level ) { char buf[1024]; size_t i; size_t size = bpipe_datatype_size( type ); if (level == 0) { fputs( prefix, stdout ); fputs( ": ", stdout ); for (i = 0 ; i < matrix->extent[level] ; i++, data = (char *) data + size) { bpipe_sprintf( buf, data, type, NULL ); fputs( buf, stdout ); if ( i < matrix->extent[level] - 1 ) fputs( " | ", stdout ); } putchar('\n'); return data; } else { for ( i = 0 ; i < matrix->extent[level] ; i++ ) { sprintf( buf, "%s[%lu]", prefix, (unsigned long) i ); data = print_data( buf, type, matrix, data, level - 1 ); } if ( level == 1 ) puts( "--------------------" ); } return data; }