/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright by The HDF Group. * * Copyright by the Board of Trustees of the University of Illinois. * * All rights reserved. * * * * This file is part of HDF. The full HDF copyright notice, including * * terms governing use, modification, and redistribution, is contained in * * the COPYING file, which can be found at the root of the source code * * distribution tree, or in https://support.hdfgroup.org/ftp/HDF/releases/. * * If you do not have access to either file, you may request a copy from * * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* $Id$ */ #include #include "mfhdf.h" #include "hdp.h" #include #ifndef MIPSEL #include #endif /* MIPSEL */ #define CARRIAGE_RETURN 13 #define LINE_FEED 10 #define HORIZONTAL_TAB 9 typedef intn (*fmtfunct_t) (VOIDP, file_format_t, FILE *); fmtfunct_t select_func(int32 nt); /* * printing functions copied from vshow.c and used by sdsdumpfull(). * * Please pay attention to the data types used in the print/output routines. * Make sure the data type being dumped matches arguments in 'fwrite()' .etc. * */ intn fmtbyte(unsigned char *x, /* assumption: byte is the same as unsigned char */ file_format_t ff, FILE *ofp) { unsigned char s; if(ff == DASCII) return (fprintf(ofp, "%02x ", (unsigned) *x)); else { s = (unsigned char) *x; return(fwrite(&s, sizeof(unsigned char),1,ofp)); } } intn fmtint8(VOIDP x, /* assumption: int8 is same as signed char */ file_format_t ff, FILE *ofp) { int8 s; if(ff == DASCII) return (fprintf(ofp, "%d", (int) *((signed char *) x))); else { s = (int8) *((signed char *) x); return(fwrite(&s, sizeof(int8), 1, ofp)); } } intn fmtuint8(VOIDP x, /* assumption: uint8 is same as unsigned char */ file_format_t ff, FILE *ofp) { uint8 s; if(ff == DASCII) return (fprintf(ofp, "%u", (unsigned) *((unsigned char *) x))); else { s = (uint8) *((unsigned char *) x); return(fwrite(&s, sizeof(uint8), 1, ofp)); } } intn fmtint16(VOIDP x, file_format_t ff, FILE *ofp) { int16 s; HDmemcpy(&s, x, sizeof(int16)); if(ff == DASCII) return (fprintf(ofp, "%d", (int) s)); else return(fwrite(&s, sizeof(int16), 1, ofp)); } intn fmtuint16(VOIDP x, file_format_t ff, FILE *ofp) { uint16 s; HDmemcpy(&s, x, sizeof(uint16)); if(ff == DASCII) return (fprintf(ofp, "%u", (unsigned) s)); else return(fwrite(&s, sizeof(uint16), 1, ofp)); } intn fmtchar(VOIDP x, file_format_t ff, FILE *ofp) { if (isprint(*(unsigned char *) x)) { putc(*((char *) x), ofp); return (1); } else { putc('\\', ofp); return (1 + fprintf(ofp, "%03o", *((uchar8 *) x))); } } intn fmtuchar8(VOIDP x, /* assumption: uchar8 is same as unsigned char */ file_format_t ff, FILE *ofp) { uchar8 s; if(ff == DASCII) /* replace %o with %d by Elena's suggestion: it doesn't make sense to print in octal - BMR 06/23/00 */ return (fprintf(ofp, "%d", *((uchar8 *) x))); else { s = (uchar8) *((unsigned char *)x); return(fwrite(&s, sizeof(uchar8),1, ofp)); } } intn fmtint(VOIDP x, /* assumption: int is same as 'intn' */ file_format_t ff, FILE *ofp) { intn i; HDmemcpy(&i, x, sizeof(intn)); if(ff == DASCII) return (fprintf(ofp, "%d", (int) i)); else return(fwrite(&i, sizeof(intn), 1, ofp)); } #define FLOAT32_EPSILON ((float32)1.0e-20) intn fmtfloat32(VOIDP x, file_format_t ff, FILE *ofp) { float32 fdata; HDmemcpy(&fdata, x, sizeof(float32)); if(ff == DASCII) { if (fabs(fdata - FILL_FLOAT) <= FLOAT32_EPSILON) return (fprintf(ofp, "FloatInf")); else return (fprintf(ofp, "%f", fdata)); } else { return(fwrite(&fdata, sizeof(float32), 1, ofp)); } } intn fmtint32(VOIDP x, file_format_t ff, FILE *ofp) { int32 l; HDmemcpy(&l, x, sizeof(int32)); if(ff == DASCII) return (fprintf(ofp, "%ld", (long) l)); else return(fwrite(&l, sizeof(int32), 1, ofp)); } intn fmtuint32(VOIDP x, file_format_t ff, FILE *ofp) { uint32 l; HDmemcpy(&l, x, sizeof(uint32)); if(ff == DASCII) return (fprintf(ofp, "%lu", (unsigned long) l)); else return(fwrite(&l, sizeof(uint32), 1, ofp)); } intn fmtshort(VOIDP x, file_format_t ff, FILE *ofp) { short s; HDmemcpy(&s, x, sizeof(short)); if(ff == DASCII) return (fprintf(ofp, "%d", (int) s)); else return(fwrite(&s, sizeof(short), 1, ofp)); } #define FLOAT64_EPSILON ((float64)1.0e-20) intn fmtfloat64(VOIDP x, file_format_t ff, FILE *ofp) { float64 d; HDmemcpy(&d, x, sizeof(float64)); if(ff == DASCII) { if (fabs(d - FILL_DOUBLE) <= FLOAT64_EPSILON) return (fprintf(ofp, "DoubleInf")); else return (fprintf(ofp, "%f", d)); } else { return(fwrite(&d, sizeof(float64), 1, ofp)); } } fmtfunct_t select_func( int32 nt) { switch (nt & 0xff ) { case DFNT_CHAR: return( fmtchar ); break; case DFNT_UCHAR: return( fmtuchar8 ); break; case DFNT_UINT8: return( fmtuint8 ); break; case DFNT_INT8: return( fmtint8 ); break; case DFNT_UINT16: return( fmtuint16 ); break; case DFNT_INT16: return( fmtint16 ); break; case DFNT_UINT32: return( fmtuint32 ); break; case DFNT_INT32: return( fmtint32 ); break; case DFNT_FLOAT32: return( fmtfloat32 ); break; case DFNT_FLOAT64: return( fmtfloat64 ); break; default: fprintf(stderr, "HDP does not support type [%d]. Use signed character printing function.\n", (int) nt); return( fmtchar ); } /* end switch */ } /* select_func */ intn dumpfull(int32 nt, dump_info_t* dump_opts, int32 cnt, /* number of items in 'databuf' ? */ VOIDP databuf, FILE *ofp, intn indent, /* indentation on the first line */ intn cont_indent ) /* indentation on the continuous lines */ { intn i; VOIDP bufptr = NULL; fmtfunct_t fmtfunct = NULL; int32 off; intn cn; file_format_t ff = dump_opts->file_format; intn ret_value = SUCCEED; /* check inputs */ if( NULL == databuf ) ERROR_GOTO_1( "in %s: Data buffer to be dumped is NULL", "dumpfull" ); if( NULL == ofp ) ERROR_GOTO_1( "in %s: Output file pointer is NULL", "dumpfull" ); /* select the appropriate function to print data elements depending on the data number type */ fmtfunct = select_func( nt ); /* assign to variables used in loop below (?)*/ bufptr = databuf; off = DFKNTsize(nt | DFNT_NATIVE); /* what is offset for data type */ if (off == FAIL) ERROR_GOTO_2("in %s: Failed to find native size of type [%d]", "dumpfull", (int)nt ); cn = cont_indent; /* current column number, cont_indent because that's where the data actually starts */ /* check if we're dumping data in ASCII or Binary mode. */ if(ff == DASCII) { /* print spaces in front of data on the first line */ for (i = 0; i < indent; i++) putc(' ', ofp); if (nt != DFNT_CHAR) { for (i = 0; i < cnt && bufptr != NULL; i++) { cn += fmtfunct(bufptr, ff, ofp); /* dump item to file */ bufptr = (char *) bufptr + off; putc(' ', ofp); cn++; /* temporary fix bad alignment algo in dumpfull by adding i < cnt-1 to remove extra line - BMR 4/10/99 */ if( !dump_opts->as_stream ) /* add \n after MAXPERLINE chars */ if (cn > MAXPERLINE && i < cnt-1 ) { putc('\n', ofp); /* print spaces in front of data on the continuous line */ for (cn = 0; cn < cont_indent; cn++) putc(' ', ofp); } /* end if */ } /* end for every item in buffer */ } else /* DFNT_CHAR */ { for (i = 0; i < cnt && bufptr != NULL; i++) { cn += fmtfunct(bufptr, ff, ofp); /* dump item to file */ bufptr = (char *) bufptr + off; if( !dump_opts->as_stream ) /* add \n after MAXPERLINE chars */ if (cn > MAXPERLINE ) { putc('\n', ofp); /* print spaces in front of data on the continuous line */ for (cn = 0; cn < cont_indent; cn++) putc(' ', ofp); } /* end if */ } /* end for every item in buffer */ } /* end else DFNT_CHAR */ putc('\n', ofp); /* newline after a dataset or attribute */ } /* end DASCII */ else /* Binary */ { for (i = 0; i < cnt && bufptr != NULL; i++) { cn += fmtfunct(bufptr, ff, ofp); /* dump item to file */ bufptr = (char *) bufptr + off; /* increment by offset? */ /* cn++; I don't see any reason of this increment being here 9/4/00*/ } /* end for all items in buffer */ } done: if (ret_value == FAIL) { /* Failure cleanup */ } /* Normal cleanup */ return ret_value; } /* dumpfull */ intn dumpclean(int32 nt, dump_info_t* dump_opts, int32 cnt, /* number of items in 'databuf' ? */ VOIDP databuf, FILE *ofp) { intn i; VOIDP bufptr = NULL; int32 off; intn cn; /* # of characters being printed on a line */ intn small_attr = TRUE; /* data buffer of the attribute is small */ intn is_null; /* TRUE if current character is a null */ char* tempptr; /* used in finding CR or LF in data buffer */ intn ret_value = SUCCEED; /* check inputs */ if( NULL == databuf ) ERROR_GOTO_1( "in %s: Data buffer to be dumped is NULL", "dumpclean" ); if( NULL == ofp ) ERROR_GOTO_1( "in %s: Output file pointer is NULL", "dumpclean" ); /* assign to variables used in loop below (?)*/ bufptr = databuf; off = DFKNTsize(nt | DFNT_NATIVE); /* what is offset for data type */ if (off == FAIL) ERROR_GOTO_2("in %s: Failed to find native size of type [%d]", "dumpclean", (int)nt ); /* set char counter to the col. #, where the first attr value will be printed in the case it is printed on the same line with "Value =" */ cn = ATTR_CONT_INDENT; /* this is the default */ is_null = FALSE; /* no null character is reached yet */ /*********************************************************************** * Requirement for printing attribute data (BMR - Oct 5, 2000): * if the attribute is large, print all data at the left most column; * otherwise (small attribute), print the first line of the data * next to the title, i.e. "Value = ", and indent the succeeding lines * ATTR_CONT_INDENT spaces. * Large attribute: buffer size is >= MAXPERLINE and the buffer * contains at least one \n (LF) or \r (CR). * Small attribute: buffer size is < MAXPERLINE or the buffer doesn't * contain any \n (LF) or \r (CR) among the data. ***********************************************************************/ /* Setting variables to prepare for the printing */ /* check the size of the buffer first, if it's shorter than MAXPERLINE then set flag small_attr. If the buffer size is larger, then proceed to the next segment which determines whether the attribute is small or large using the space char. criteria. */ if( cnt < MAXPERLINE ) small_attr = TRUE; /* if the buffer contains at least one \n (LF) or \r (CR), reset flag small_attr to indicate the attribute is considred large. */ else /* space char. criteria */ { tempptr = strchr( (char *) bufptr, '\n'); /* find the first linefeed */ if( tempptr != NULL) /* if an LF is found within the data buffer */ { putc('\n', ofp); /* start first line of data on the next line */ small_attr = FALSE; /* indicate data buffer contains CRs or LFs */ } else /* no LF, maybe CR is there */ { tempptr = strchr( (char *) bufptr, '\r'); if( tempptr != NULL) /* if a CR is found within the data buffer */ { putc('\n', ofp); /* start first line of data on the next line */ small_attr = FALSE; /* indicate data buffer contains CRs or LFs */ } } } /* space char. criteria */ /* for each character in the buffer, print it accordingly */ for (i = 0; i < cnt; i++) { /* if number of characters printed on the current line reaches the max defined and the data buffer doesn't contain any LF or CR, print a new line and indent appropriately. Note: this statement is at the top here is to prevent the extra line and indentation when the last line of the attribute data just reached MAXPERLINE */ if (cn >= MAXPERLINE && small_attr ) { putc('\n', ofp); for (cn = 0; cn < ATTR_CONT_INDENT; cn++) putc(' ', ofp); } /* end if */ /* if the current character is printable */ if (isprint(*(unsigned char *) bufptr)) { /* if there has been null characters before this non-null char, print "..." */ if( is_null ) { cn = cn + fprintf( ofp, " ... " ); is_null = FALSE; /* reset flag */ } /* then print the current non-null character */ putc(*((char *) bufptr), ofp); cn++; /* increment character count */ } /* when a \0 is reached, do not print it, set flag for its existence, so when a non-null char is reached, "..." can be printed */ else if( *(unsigned char *) bufptr == '\0') is_null = TRUE; /* when a space character, such as LF, CR, or tab, is reached, print it and increment the character counter accordingly */ else if( isspace(*(unsigned char *) bufptr)) { /* when either LF or CR exists in the data buffer, character counter, cn, is no longer needed since we don't need to keep track of the number of chars being printed on a line anymore. Yet, for logical purpose, reset it here just as a new line of data starts */ if( *(unsigned char *) bufptr == CARRIAGE_RETURN || *(unsigned char *) bufptr == LINE_FEED ) { putc('\n', ofp); /* print \n for both CR and LF, otherwise, CR=^M*/ cn = 0; /* indicating that next data element will be printed at column 1 */ } else if( *(unsigned char *) bufptr == HORIZONTAL_TAB ) { putc(*((char *) bufptr), ofp); cn = cn + 8; /* compensate for the tab, at most 8 chars */ } /* keep this else here to take care of other isspace cases, fill in more cases as need; if all cases are taken care of, remove else */ else { putc('\\', ofp); cn = cn + fprintf(ofp, "%03o", *((uchar8 *) bufptr)); } } else { /* this should be printed as binary intstead of \digits */ putc('\\', ofp); cn = cn + fprintf(ofp, "%03o", *((uchar8 *) bufptr)); } /* advance the buffer pointer */ bufptr = (char *) bufptr + off; /* Move here to avoid internal compiler error on Cray J90 -QAK */ if(bufptr==NULL) break; } /* end for every item in buffer */ putc('\n', ofp); /* newline */ done: if (ret_value == FAIL) { /* Failure cleanup */ } /* Normal cleanup */ return ret_value; } /* dumpclean */