Mercurial > hg > octave-lyh
changeset 471:32fb3a762074
[project @ 1994-06-06 08:55:13 by jwe]
author | jwe |
---|---|
date | Mon, 06 Jun 1994 08:55:32 +0000 |
parents | 693d18604ccb |
children | 33fe06de2c90 |
files | liboctave/dMatrix.cc liboctave/dMatrix.h src/file-io.cc |
diffstat | 3 files changed, 172 insertions(+), 311 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/dMatrix.cc +++ b/liboctave/dMatrix.cc @@ -2223,7 +2223,7 @@ * Read an array of data froma file in binary format. */ int -Matrix::read (FILE *fptr, int size, Matrix::conversion conv) +Matrix::read (FILE *fptr, char *type) { // Allocate buffer pointers. @@ -2232,7 +2232,6 @@ void *vd; char *ch; u_char *uc; -// s_char *sc; // Some systems may need this? short *sh; u_short *us; int *in; @@ -2244,73 +2243,54 @@ } buf; - buf.db = fortran_vec (); - -// Read data directly into matrix data array. - - int count = fread (buf.ch, size, length (), fptr); - // Convert data to double. - int k; - - switch (conv) + if (! type) { - case CNV_DOUBLE: - break; - - case CNV_CHAR: - for (k = count - 1; k > -1; k--) - buf.db[k] = buf.ch[k]; - break; + (*current_liboctave_error_handler) + ("fread: invalid NULL type parameter"); + return 0; + } - case CNV_UCHAR: - for (k = count - 1; k > -1; k--) - buf.db[k] = buf.uc[k]; - break; + int count; + int nitems = length (); -// Some systems may need this?? -// case CNV_SCHAR: -// for (k = count - 1; k > -1; k--) -// buf.db[k] = buf.sc[k]; -// break; - - case CNV_SHORT: - for (k = count - 1; k > -1; k--) - buf.db[k] = buf.sh[k]; - break; + double *d = fortran_vec (); // Ensures only one reference to my privates! - case CNV_USHORT: - for (k = count - 1; k > -1; k--) - buf.db[k] = buf.us[k]; - break; - - case CNV_INT: - for (k = count - 1; k > -1; k--) - buf.db[k] = buf.in[k]; - break; - - case CNV_UINT: - for (k = count - 1; k > -1; k--) - buf.db[k] = buf.ui[k]; - break; +#define DO_FREAD(TYPE,ELEM) \ + do \ + { \ + size_t size = sizeof (TYPE); \ + buf.ch = new char [size * nitems]; \ + count = fread (buf.ch, size, nitems, fptr); \ + for (int k = 0; k < count; k++) \ + d[k] = buf.ELEM[k]; \ + delete [] buf.ch; \ + } \ + while (0) - case CNV_LONG: - for (k = count - 1; k > -1; k--) - buf.db[k] = buf.ln[k]; - break; - - case CNV_ULONG: - for (k = count - 1; k > -1; k--) - buf.db[k] = buf.ul[k]; - break; - - case CNV_FLOAT: - for (k = count - 1; k > -1; k--) - buf.db[k] = buf.fl[k]; - break; - - default: + if (strcasecmp (type, "double") == 0) + DO_FREAD (double, db); + else if (strcasecmp (type, "char") == 0) + DO_FREAD (char, ch); + else if (strcasecmp (type, "uchar") == 0) + DO_FREAD (u_char, uc); + else if (strcasecmp (type, "short") == 0) + DO_FREAD (short, sh); + else if (strcasecmp (type, "ushort") == 0) + DO_FREAD (u_short, us); + else if (strcasecmp (type, "int") == 0) + DO_FREAD (int, in); + else if (strcasecmp (type, "uint") == 0) + DO_FREAD (u_int, ui); + else if (strcasecmp (type, "long") == 0) + DO_FREAD (long, ul); + else if (strcasecmp (type, "float") == 0) + DO_FREAD (float, fl); + else + { + (*current_liboctave_error_handler) + ("fread: invalid NULL type parameter"); return 0; } @@ -2321,7 +2301,7 @@ * Write the data array to a file in binary format. */ int -Matrix::write (FILE *fptr, int size, Matrix::conversion conv) +Matrix::write (FILE *fptr, char *type) { // Allocate buffer pointers. @@ -2330,7 +2310,6 @@ void *vd; char *ch; u_char *uc; -// s_char *sc; // Some systems may need this? short *sh; u_short *us; int *in; @@ -2342,84 +2321,60 @@ } buf; - int len = length (); + int nitems = length (); - if (conv != CNV_DOUBLE) - buf.db = new double [len]; - - double *bufi = fortran_vec (); + double *d = fortran_vec (); // Convert from double to correct size. - int k; - - switch (conv) + if (! type) { - case CNV_DOUBLE: - buf.db = bufi; - break; + (*current_liboctave_error_handler) + ("fwrite: invalid NULL type parameter"); + return 0; + } - case CNV_CHAR: - for (k = 0; k < len; k++) - buf.ch[k] = (char) bufi[k]; - break; + size_t size; + int count; - case CNV_UCHAR: - for (k = 0; k < len; k++) - buf.uc[k] = (u_char) bufi[k]; - break; - -// Some systems may need this? -// case CNV_SCHAR: -// for (k = 0; k < len; k++) -// buf.uc[k] = (s_char) bufi[k]; -// break; - - case CNV_SHORT: - for (k = 0; k < len; k++) - buf.sh[k] = (short) bufi[k]; - break; - - case CNV_USHORT: - for (k = 0; k < len; k++) - buf.us[k] = (u_short) bufi[k]; - break; +#define DO_FWRITE(TYPE,ELEM) \ + do \ + { \ + size = sizeof (TYPE); \ + buf.ELEM = new TYPE [nitems]; \ + for (int k = 0; k < nitems; k++) \ + buf.ELEM[k] = (TYPE) d[k]; \ + count = fwrite (buf.ELEM, size, nitems, fptr); \ + delete [] buf.ELEM; \ + } \ + while (0) - case CNV_INT: - for (k = 0; k < len; k++) - buf.in[k] = (int) bufi[k]; - break; - - case CNV_UINT: - for (k = 0; k < len; k++) - buf.ui[k] = (u_int) bufi[k]; - break; - - case CNV_LONG: - for (k = 0; k < len; k++) - buf.ln[k] = (long) bufi[k]; - break; - - case CNV_ULONG: - for (k = 0; k < len; k++) - buf.ul[k] = (u_long) bufi[k]; - break; - - case CNV_FLOAT: - for (k = 0; k < len; k++) - buf.fl[k] = (float) bufi[k]; - break; - - default: + if (strcasecmp (type, "double") == 0) + DO_FWRITE (double, db); + else if (strcasecmp (type, "char") == 0) + DO_FWRITE (char, ch); + else if (strcasecmp (type, "uchar") == 0) + DO_FWRITE (u_char, uc); + else if (strcasecmp (type, "short") == 0) + DO_FWRITE (short, sh); + else if (strcasecmp (type, "ushort") == 0) + DO_FWRITE (u_short, us); + else if (strcasecmp (type, "int") == 0) + DO_FWRITE (int, in); + else if (strcasecmp (type, "uint") == 0) + DO_FWRITE (u_int, ui); + else if (strcasecmp (type, "long") == 0) + DO_FWRITE (long, ln); + else if (strcasecmp (type, "ulong") == 0) + DO_FWRITE (u_long, ul); + else if (strcasecmp (type, "float") == 0) + DO_FWRITE (float, fl); + else + { + (*current_liboctave_error_handler) + ("fwrite: unrecognized type parameter %s", type); return 0; - } - -// Write data from converted matrix data array. - - int count = fwrite (buf.ch, size, length (), fptr); - - if (conv != CNV_DOUBLE) - delete [] buf.db; + } return count; }
--- a/liboctave/dMatrix.h +++ b/liboctave/dMatrix.h @@ -227,25 +227,8 @@ friend ostream& operator << (ostream& os, const Matrix& a); friend istream& operator >> (istream& is, Matrix& a); - enum conversion - { - CNV_UNKNOWN, - CNV_UCHAR, - CNV_CHAR, - CNV_SCHAR, - CNV_SHORT, - CNV_USHORT, - CNV_INT, - CNV_UINT, - CNV_LONG, - CNV_ULONG, - CNV_FLOAT, - CNV_DOUBLE, - }; - - - int read (FILE *fptr, int size, Matrix::conversion); - int write (FILE *fptr, int size, Matrix::conversion); + int read (FILE *fptr, char *type); + int write (FILE *fptr, char *type); // Until templates really work with g++:
--- a/src/file-io.cc +++ b/src/file-io.cc @@ -1208,114 +1208,46 @@ } /* - * Find out how many elements are left. - * - * size is the size of the elements - * nr is the number of rows or columns in the matrix + * Find out how many elements are left to read. */ static long -get_whats_left (FILE *fptr, int size, int nn) +num_items_remaining (FILE *fptr, char *type) { + size_t size; + + if (strcasecmp (type, "uchar") == 0) + size = sizeof (u_char); + else if (strcasecmp (type, "char") == 0) + size = sizeof (char); + else if (strcasecmp (type, "short") == 0) + size = sizeof (short); + else if (strcasecmp (type, "ushort") == 0) + size = sizeof (u_short); + else if (strcasecmp (type, "int") == 0) + size = sizeof (int); + else if (strcasecmp (type, "uint") == 0) + size = sizeof (u_int); + else if (strcasecmp (type, "long") == 0) + size = sizeof (long); + else if (strcasecmp (type, "ulong") == 0) + size = sizeof (u_long); + else if (strcasecmp (type, "float") == 0) + size = sizeof (float); + else if (strcasecmp (type, "double") == 0) + size = sizeof (double); + else + return 0; + long curr_pos = ftell (fptr); fseek (fptr, 0, SEEK_END); long end_of_file = ftell (fptr); - fseek (fptr, end_of_file, SEEK_SET); + fseek (fptr, curr_pos, SEEK_SET); long len = end_of_file - curr_pos; - long num_items = len / size / nn; - - if (len > num_items * size * nn) - num_items++; - - return num_items; -} - -static void -get_size_conv (const char *preci, int& size, Matrix::conversion& conv, - const char *warn) -{ -// Get type and number of bytes per element to read. - - char *prec = strdup (preci); - char *ip = prec; - - while (*ip > 0) - { - tolower (*ip); - ip++; - } - - if (strcmp (prec, "uchar") == 0) - { - size = 1; - conv = Matrix::CNV_UCHAR; - } - else if (strcmp (prec, "char") == 0) - { - size = 1; - conv = Matrix::CNV_CHAR; - } - else if (strcmp (prec, "schar") == 0) - { - size = 1; - conv = Matrix::CNV_CHAR; -// Some systems may need this?? -// size = 1; -// conv = CNV_SCHAR; - } - else if (strcmp (prec, "short") == 0) - { - size = 2; - conv = Matrix::CNV_SHORT; - } - else if (strcmp (prec, "ushort") == 0) - { - size = 2; - conv = Matrix::CNV_USHORT; - } - else if (strcmp (prec, "int") == 0) - { - size = 4; - conv = Matrix::CNV_INT; - } - else if (strcmp (prec, "uint") == 0) - { - size = 4; - conv = Matrix::CNV_UINT; - } - else if (strcmp (prec, "long") == 0) - { - size = 4; - conv = Matrix::CNV_LONG; - } - else if (strcmp (prec, "ulong") == 0) - { - size = 4; - conv = Matrix::CNV_ULONG; - } - else if (strcmp (prec, "float") == 0) - { - size = 4; - conv = Matrix::CNV_FLOAT; - } - else if (strcmp (prec, "double") == 0) - { - size = 8; - conv = Matrix::CNV_DOUBLE; - } - else - { - error ("%s: precision: \'%s\' unknown", warn, prec); - size = -1; - conv = Matrix::CNV_UNKNOWN; - } - - delete [] prec; - - return; + return len / size; } /* @@ -1364,86 +1296,87 @@ } } - int size; - Matrix::conversion conv; - get_size_conv (prec, size, conv, "fread"); - if (size < 0) - return retval; +// Get file info. -// Get file info. file_info file = file_list (p); - FILE * fptr = file.fptr (); + + FILE *fptr = file.fptr (); // Set up matrix to read into. If specified in arguments use that // number, otherwise read everyting left in file. - double dnr = 1.0; - double dnc = 1.0; - int nr = 1; - int nc = 1; + double dnr = 0.0; + double dnc = 0.0; + int nr; + int nc; if (nargin > 2) { -// tree_constant tmpa = args[2].make_numeric (); // ?? - if (args[2].is_scalar_type ()) { tree_constant tmpa = args[2].make_numeric (); - - dnr = 1.0; - dnc = tmpa.double_value (); + dnr = tmpa.double_value (); + dnc = 1.0; } else if (args[2].is_matrix_type ()) { -// tree_constant tmpa = args[2].make_numeric (); // ?? - Matrix tmpm = args[2].to_matrix (); - nr = tmpm.rows (); - nc = tmpm.columns (); + ColumnVector tmp = args[2].to_vector (); - if(nr != 1 || nc > 2) + if (tmp.length () == 2) + { + dnr = tmp.elem (0); + dnc = tmp.elem (1); + } + else + { + error ("fread: invalid size specification\n"); + return retval; + } + } + + if ((xisinf (dnr)) && (xisinf (dnc))) { - error ("fread: Illegal size specification\n"); - print_usage ("fread"); + error ("fread: number of rows and columns cannot both be infinite"); return retval; } - dnr = tmpm.elem (0, 0); - dnc = tmpm.elem (0, 1); - } - if ((xisinf (dnr)) && (xisinf (dnc))) - { - error ("fread: number of rows and columns cannot both be infinite\n"); - return retval; - } - - if (xisinf (dnr)) - { - nc = NINT (dnc); - nr = get_whats_left (fptr, size, nc); - } - else if (xisinf (dnc)) - { - nr = NINT (dnr); - nc = get_whats_left (fptr, size, nr); - } - else - { - nr = NINT (dnr); - nc = NINT (dnc); - } + if (xisinf (dnr)) + { + nc = NINT (dnc); + int n = num_items_remaining (fptr, prec); + nr = n / nc; + if (n > nr * nc) + nr++; + } + else if (xisinf (dnc)) + { + nr = NINT (dnr); + int n = num_items_remaining (fptr, prec); + nc = n / nr; + if (n > nc * nr) + nc++; + } + else + { + nr = NINT (dnr); + nc = NINT (dnc); + } } else { // No size parameter, read what's left of the file. - nr = 1; - nc = get_whats_left (fptr, size, nr); + nc = 1; + int n = num_items_remaining (fptr, prec); + nr = n / nc; + if (n > nr * nc) + nr++; } Matrix m (nr, nc, octave_NaN); // Read data. - int count = m.read (fptr, size, conv); + int count = m.read (fptr, prec); if (nargout > 1) { @@ -1497,21 +1430,11 @@ } } - int size; - Matrix::conversion conv; - get_size_conv(prec, size, conv, "fwrite"); - if (size < 0) - return retval; - -// Get file info. file_info file = file_list (p); -// Write the matrix data. - tree_constant tmpa = args[2].make_numeric (); + Matrix m = args[2].to_matrix (); - Matrix tmpm = tmpa.to_matrix (); - - int count = tmpm.write (file.fptr(), size, conv); + int count = m.write (file.fptr (), prec); retval = new tree_constant[2]; retval[0] = tree_constant ((double) count);